We want to show how you can improve performance of your application by using WASM/WASI. To show this, we're using an estimation algorithm to calculate pi.
By implementing this in different languages and benchmarking it, we can see if you can achieve some speed improvements.
This repository is not here to bash Python, there are other repositories, blogs which do this a lot better. This repository is here to show how to gradually improve your existing codebase.
Pi is a very interesting number. Although you can find the digit easily in libraries or in documentation, we still want to calculate it ourselves.
We want to estimate pi with Monte Carlo by throwing f.e. 5_000_000 (virtual) darts at a board. The number of hits inside the board can be used to calculate pi.
Number of dart throwing: 5_000_000
We're using four implementations of the algorithm:
- Python version in /python.
- Rust version in /rust.
- Python calling Rust with cffi version in /hybrid.
- Python calling Rust with WASM/WASI version in /wasm.
We're using the hyperfine benchmark tool.
brew install hyperfine
Run pi-monte-carlo algorithm in pure Python!
Click to expand!
python python/pi-monte-carlo.py
Commando:
hyperfine -w 2 -m 10 'python python/pi-monte-carlo.py'
Result (Ran on my macbook pro):
Benchmark #1: python python/pi-monte-carlo.py
Time (mean ± σ): 3.184 s ± 0.072 s [User: 3.083 s, System: 0.077 s]
Range (min … max): 3.090 s … 3.314 s 10 runs
Run pi-monte-carlo algorithm in pure Rust!
Click to expand!
cargo run --manifest-path rust/pi-monte-carlo/Cargo.toml
Commando:
cargo build --release --manifest-path rust/pi-monte-carlo/Cargo.toml
hyperfine -w 2 -m 10 './rust/pi-monte-carlo/target/release/pi-monte-carlo'
Result (Ran on my macbook pro):
Benchmark #1: ./rust/pi-monte-carlo/target/release/pi-monte-carlo
Time (mean ± σ): 64.6 ms ± 1.5 ms [User: 60.4 ms, System: 2.7 ms]
Range (min … max): 63.4 ms … 72.3 ms 41 runs
Use FFI to call the Rust monte-carlo-pi loop from Python.
Click to expand!
pip install cffi
cargo build --release --manifest-path hybrid/pi-monte-carlo/Cargo.toml
python hybrid/pi-monte-carlo.py
Commando:
cargo build --release --manifest-path hybrid/pi-monte-carlo/Cargo.toml
hyperfine -w 2 -m 10 'python hybrid/pi-monte-carlo.py'
Result (Ran on my macbook pro):
Benchmark #1: python hybrid/pi-monte-carlo.py
Time (mean ± σ): 226.1 ms ± 1.7 ms [User: 139.4 ms, System: 81.8 ms]
Range (min … max): 222.5 ms … 229.2 ms 12 runs
Fast
Target specific libs. For each OS you have a different binary. For mac for a .dylib
file. For windows a .dll
.
Using WASM/WASI to call the Rust monte-carlo-pi loop from Python.
Click to expand!
cargo install wasm-gc
pip install wasmtime
cargo build --target wasm32-wasi --release --manifest-path wasm/pi-monte-carlo/Cargo.toml
ln -s pi-monte-carlo/target/wasm32-wasi/release/pi_monte_carlo.wasm wasm/pi_monte_carlo.wasm
wasm-gc wasm/pi-monte-carlo/target/wasm32-wasi/release/pi_monte_carlo.wasm
python wasm/pi-monte-carlo.py
Commando:
cargo build --target wasm32-wasi --release --manifest-path wasm/pi-monte-carlo/Cargo.toml
ln -s wasm/pi-monte-carlo/target/wasm32-wasi/release/pi_monte_carlo.wasm wasm
hyperfine -w 2 -m 10 'python wasm/pi-monte-carlo.py'
Result (Ran on my macbook pro):
Benchmark #1: python wasm/pi-monte-carlo.py
Time (mean ± σ): 1.551 s ± 0.069 s [User: 1.454 s, System: 0.087 s]
Range (min … max): 1.479 s … 1.715 s 10 runs
- No platform specific binaries.
- Sandboxed environment.
- Can be called from almost any language / platform.
- Not so fast