Gregory Hildstrom Projects Publications Resume Contact About Youtube Donate

Rust WASM Performance Comparison

Introduction

A few years ago, I did a programming language performance comparison and a memory management and automatic garbage collection comparison. Recently, Rust and Swift caught my interest and I did a C, Rust, and Swift performance and memory comparison. Now, Web Assembly (WASM) and WASM System Interface (WASI) have popped up on my radar. So I decided to learn a bit by comparing the performance of the same Rust code running natively and via WASM/WASI. My test system is a 2018 MacBook Pro 6-core i9, with 32GB RAM, running macOS Catalina 10.15.

Performance Comparison Code

perf.rs
use std::env;

fn main() {
    let iterations: usize;
    let mut sum: f64 = 0.0;
    let array_length: usize = 100000000;
    let args: Vec< String > = env::args().collect();
    let mut array: Vec< f64 > = vec![0.0; array_length];

    iterations = (&args[1]).parse().expect("Not a number");

    println!("iterations {}", iterations);

    for element in 0..array_length {
        array[element] = element as f64;
    }

    for iteration in 0..iterations {
        for innerloop in 0..1000000000 {
            sum += array[(iteration + innerloop) % array_length];
        }
    }

    println!("sum {}", sum);
}

Performance Results

The performance of WASM via wasmtime was obviously slower than native execution. Based on the measured relationship and past tests, WASM/wasmtime is slower than native and Java, but faster than Go, Node JS, and Lua. Resident memory usage of both was very similar during the test.



Makefile

all: \
perf-rust \
perf-rust.wasm \
mem-rust \
mem-rust.wasm \


perf-rust: perf.rs
	rustc -C opt-level=3 -o perf-rust perf.rs

perf-rust.wasm: perf.rs
	rustc --target=wasm32-wasi -C opt-level=3 -o perf-rust.wasm perf.rs

mem-rust: mem.rs
	rustc -C opt-level=3 -o mem-rust mem.rs

mem-rust.wasm: mem.rs
	rustc --target=wasm32-wasi -C opt-level=3 -o mem-rust.wasm mem.rs

clean:
	rm -f *.o *.so
	rm -f perf-rust
	rm -f perf-rust.wasm
	rm -f mem-rust
	rm -f mem-rust.wasm

run_perf_test: all
	echo "-------------------------------------"
	time -p ./perf-rust 100
	time -p wasmtime perf-rust.wasm 100
	echo "-------------------------------------"

run_mem_test: all
	echo "-------------------------------------"
	./capture.sh mem-rust &
	./mem-rust ; sleep 2
	./capture.sh mem-rust.wasm &
	wasmtime mem-rust.wasm ; sleep 2
	echo "-------------------------------------"