What's in the box
- WebAssembly with Rust
- Benchmark with fancy charts
- Web Workers to avoid a frozen main thread
- Build and deploy with Travis CI
Rust and WebAssembly
There are two books that fully cover this section:
Source code is splitted into two main folders:
src that contains our Rust application and
I tried to make their folder structure as similar as possible:
src ├── libs │ ├── mod.rs │ ├── ... │ └── primes.rs └── main.rs src-js ├── libs │ ├── mod.js │ ├── ... │ └── primes.js ├── ... ├── bootstrap.js └── main.js
*/libs/mod.* is the entry point for declaring all modules. The
.rs version of this file will be compiled to
*/main.* is the entry point for the application. The
.rs file is the one used by
cargo run command. The
.js file is the one used by webpack.
./src-js/bootstrap.js is the bootstrap file for the web application that loads the
main.js file asynchronously.
The first step is to install Rust. We’ll download Rust through
rustup, a command line tool for managing Rust versions and associated tools.
$ curl https://sh.rustup.rs -sSf | sh # install `wasm-pack` $ curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh # update dependencies $ cargo update
Now we are able to use the following commands from our project folder.
# test .rs files $ cargo test # compile `src/main.rs` $ cargo build Finished dev [unoptimized + debuginfo] target(s) # or compile `src/main.rs` with optimizations $ cargo build --release Finished release [optimized] target(s)
Now that we have built our code, we can run it:
$ ./target/release/wasm-vs-js-benchmark primes-get_primes 11
We can also use
cargo run to compile and then run it, all in one step:
$ cargo run primes-get_primes 11 # compile and run our project with optimizations $ cargo run --release primes-get_primes 11
Last but not least, we'll compile our project to
$ wasm-pack build
Now we are able to use the content of
./pkg folder for our web application.
Web Workers makes it possible to run a script operation in a background thread separate from the main execution thread of a web application.
The web application is bundled with
Run following command to start it:
$ npm run build:wasm $ npm start
Project is running at http://localhost:8080/
Rust to Native Code
The execution time of .wasm binaries is just a bit slower than the execution of same native code.
For benchmarking the native code, I use Hyperfine.
These benchmarks are recorded on a MacBook Pro (15-inch, 2016) having these specs:
- macOS Mojave
- 2,6 GHz Intel Core i7 (4 cores)
- 16 GB 2133 MHz LPDDR3
$ cargo build --release $ hyperfine --warmup 3 --export-markdown BENCHMARK.md \ './target/release/wasm-vs-js-benchmark primes-get_primes 100000' \ './target/release/wasm-vs-js-benchmark matrix-multiply 500 500'
|Command||Mean [s]||Min…Max [s]|
||1.211 ± 0.018||1.196…1.255|
||0.435 ± 0.016||0.417…0.469|