为什么 Rust WASM 在计算素数时比 JavaScript 慢

Luk*_*uke 10 javascript performance rust webassembly rust-wasm

我编写了一段非常基本的代码来计算 Rust(编译为 WASM)和 JavaScript 中的数字是否为素数,以对算术性能进行基准测试。

我满心期待 Rust/WASM 能够打败 JavaScript。在我做过的所有其他算术基准测试中,Rust/WASM 似乎比 JavaScript 更有优势,或者至少与之匹配。然而,在这个测试中,JavaScript 似乎远远优于 WASM,我并没有真正解释为什么会这样。

生锈代码:

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()
}
Run Code Online (Sandbox Code Playgroud)

JavaScript 代码:

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)}`);
Run Code Online (Sandbox Code Playgroud)

基本示例项目:https://github.com/Mcluky/Stack-Overflow-Rust-Wasm-Performance-Example

我已经检查/完成的事情:

  • 我确保--release在构建 Rust 代码时始终设置标志。
  • 直接在我的机器上运行 Rust 代码,这比 JS 和 WASM 都快得多,所以我怀疑它与 WASM 目标有关。
  • 由于 JavaScript 使用浮点数,因此在 Rust 中将整数类型 (u64) 替换为浮点数 (f64),但我得到了类似的结果。
  • 经过迭代测试以确保其一致性。
  • 尝试while而不是for-in在 Rust 版本中,以防它没有你想象的那么优化。

orl*_*rlp 2

我无法在 Windows 10 上的 Ryzen Threadripper 2950x 上重现您的结果。我添加了以下函数:

#[wasm_bindgen]
pub fn bench_rs(max: u64) -> u64 {
    (1..=max).map(|n| calculate_is_prime_rs(n) as u64).sum()
}
Run Code Online (Sandbox Code Playgroud)
function bench_js(max) {
    let tot = 0;
    for (let n = 1; n <= max; n++) {
        tot += calculateIsPrime(n);
    }
    return tot;
}
Run Code Online (Sandbox Code Playgroud)

wasm-pack build --release --target web然后我在 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
Run Code Online (Sandbox Code Playgroud)

在火狐浏览器中:

> 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
Run Code Online (Sandbox Code Playgroud)