DEV Community

Increase Rust and WebAssembly performance πŸš€πŸš€πŸš€

Sendil Kumar on July 02, 2019

The dream of running native code in the browser is not something new. There were many failed attempts. They all taught us a lesson. Those learnings...
Collapse
 
joshcheek profile image
Josh Cheek • Edited

How long should it take to bundle? I've been waiting for a really long time... like four minutes, and it still says "wait until bundle finished:"

https://thepracticaldev.s3.amazonaws.com/i/n51ddfxad6dnk7wq0pgr.png

Collapse
 
joshcheek profile image
Josh Cheek • Edited

Okay, it took ~10 minutes, but once it got going, it was able to live-reload in a few seconds.

Here's the JS I used:

import marked from 'marked'
import("../pkg/index.js")
  .then(module => {
    const markdown = '# some markdown content'

    console.time('rust')
    console.log({ rust: module.parse(markdown) })
    console.timeEnd('rust')

    console.time('js')
    console.log({ js: marked(markdown) })
    console.timeEnd('js')
  })
  .catch(console.error)

And the result (Safari 12.11):

[Log] {rust: "<h1>some markdown content</h1>↡"}
[Debug] rust: 12.227ms
[Log] {js: "<h1 id=\"some-markdown-content\">some markdown content</h1>↡"}
[Debug] js: 3.981ms
Collapse
 
joshcheek profile image
Josh Cheek

Hold up, I'm going to update my rust and add the optimizations and see what sizes and times we get.

Thread Thread
 
joshcheek profile image
Josh Cheek

Okay, updated them and compiled with opt-level=3, and wee_alloc on. Compilation took a really long time, but I get that it's a prod feature, not a dev feature. Wasm file was 1.3Mb, though :/

I tried compiling with s and z to see the file size difference, but it failed to compile when I tried that (it deleted the pkg directory and then didn't regenerate it)

$ rustc --version
rustc 1.37.0-nightly (088b98730 2019-07-03)


$ cat Cargo.toml | sed -n '/profile.dev/,/default/p'
[profile.dev]
lto = true
opt-level = 3

[features]
# If you uncomment this line, it will enable `wee_alloc`:
default = ["wee_alloc"]

$ du -h pkg/index_bg.wasm
1.3M    pkg/index_bg.wasm

# durations:
# rust: between 1 and 3.5 ms (usually between 1 and 2)
# js:   between 2.5 and 3.5ms

Anyway, good article, thanks for writing it up :)

Thread Thread
 
sendilkumarn profile image
Sendil Kumar • Edited

What was the error message when you did s and z? You should pass it as a String.

All the above tests are run on rustc 1.37.0-nightly (929b48ec9 2019-06-21)

WASM file size is around that value, this may change in the future. 🀞

Thread Thread
 
joshcheek profile image
Josh Cheek

Oh, that's probably what I did wrong, I just had opt-level=s, not opt-level="s"

The error wasn't interesting, it was about how it tried to import the index, but the file wasn't there. I'm 90% sure it originated in the browser and that the server was just echoing it for me to see. Other than that, it just said "build failed". Which is interesting, because when I set it to opt-level=5, it told me that the only valid values were 1-3, and s and z, so it's a bit surprising that I didn't get that error again).

Collapse
 
sendilkumarn profile image
Sendil Kumar

It is installing wasm-pack and then wasm bindgen cli. If this the first time, then it might take sometime. Try installing manually and check if it fails. Check out wasm-pack docs for this. successive runs will be faster

Collapse
 
adam_cyclones profile image
Adam Crockett πŸŒ€

So I have been tinkering with this mad project, and now I have learned that c++ is very verbose, do you find rust easier to write, manage and understand. I'm contemplating version 2 in rust with rlua.

GitHub logo acronamy / tidal-node

Node.js tidal is my experiment to transparently integrate Lua and Lua rocks (TODO) into a simple node library via WASM. *optionally* Want to require Lua scripts from Node and have it give you a table? Want to use node features in Lua?

Tidal Node

Lua was concieved as an embeded language, designed to compliment other languages, Tidal Node is a library which brings Lua to node.js through WebAssembly and c++.

Tidal Node is WIP and not production ready - however I welcome the one or two people in the world that want to use this to get those PR's coming in. You will find most of the emscripten compiler commands in npm package.json "config". There is also a installer task for Lua built in, everything is subject to change.

Requirements

compiler:

emscripten 1.38.30^

runtime:

node 10.0.0^

build tools:

  • make
  • curl

Commands

command purpose
npm start just run the project
npm run compile just compile
npm run install-lua download a copy of lua 5.3.5 and build with emscripten

What is working

  • Return flat Lua tables to node!

Highlights - "It's alive!"

  • Returning flat Lua Tables to JavaScript as Objects
  • Use module.exports and require…




Collapse
 
sendilkumarn profile image
Sendil Kumar

Thats a great idea πŸ‘πŸŽ‰ Yeah Rust is very concise. When you start you have wrap your head around the ownership, lifetimes and others. But when you get the feeling for that, then it will be much more easier and simpler to write.

Collapse
 
adam_cyclones profile image
Adam Crockett πŸŒ€

Thank you for your kind words. So there's no emscripten, sounds interesting! Okay well I'm gonna carry on getting this version done and rolled out before giving this a shot.