I wrote a very rudimentary piece of code to calculate if a number is prime in Rust (compiled to WASM) and in JavaScript to benchmark the arithmetic performance.
I was fully expecting Rust/WASM to blow away JavaScript. In all other arithmetic benchmarks I've done Rust/WASM seems to have the edge over JavaScript or at least match it. However in this test, JavaScript seems to heavily outperform WASM and I don't really have an explanation to why that is.
Rust Code:
pub fn calculate_is_prime(number: u64) -> bool {
if number == 1 {
return false;
}
if number == 2 {
return true;
}
for i in 2..number {
if number % i == 0 {
return false;
}
}
return true;
}
#[wasm_bindgen]
pub fn bench_rs(max: u64) -> u64 {
(1..=max).map(|n| calculate_is_prime_rs(n) as u64).sum()
}
JavaScript code:
function calculateIsPrime(number) {
if (number === 1) {
return false;
}
if (number === 2) {
return true;
}
for (let i = 2; i < number; i++) {
if (number % i === 0) {
return false;
}
}
return true;
}
function bench_js(max) {
let tot = 0;
for (let n = 1; n <= max; n++) {
tot += calculateIsPrime(n);
}
return tot;
}
let max = 200000;
console.log(`Amount of primes under ${max} is ${bench_js(max)}`);
Basic sample project: https://github.com/Mcluky/Stack-Overflow-Rust-Wasm-Performance-Example
Things I've already checked/done:
--release flag while building the rust code.while instead of for-in in the Rust version in case it wasn't as optimized as you'd think.I can not reproduce your results on a Ryzen Threadripper 2950x on Windows 10. I added the following functions:
#[wasm_bindgen]
pub fn bench_rs(max: u64) -> u64 {
(1..=max).map(|n| calculate_is_prime_rs(n) as u64).sum()
}
function bench_js(max) {
let tot = 0;
for (let n = 1; n <= max; n++) {
tot += calculateIsPrime(n);
}
return tot;
}
I then compiled with wasm-pack build --release --target web and evaluated in both Google Chrome:
> console.time("rs"); console.log(bench_rs(BigInt(200000))); console.timeEnd("rs");
17984n
rs: 6015.033935546875 ms
> console.time("js"); console.log(bench_js(200000)); console.timeEnd("js");
17984
js: 6017.426025390625 ms
And in Firefox:
> console.time("rs"); console.log(bench_rs(BigInt(200000))); console.timeEnd("rs");
17984n
rs: 6076ms - timer ended
> console.time("js"); console.log(bench_js(200000)); console.timeEnd("js");
17984
js: 6074ms - timer ended