为什么JS/React比WebAssembly/Rust更快?

4
我正在使用由Rust(wasm_bindgen)生成的Wasm进行一些测试。令我惊讶的是,JavaScript实现似乎比Rust实现要快得多。
该程序正在创建n个字典/对象/映射项,并将其推送到数组中。
JavaScript实现非常简单:
const createJSObjects = (amount: number) => {
  const arr: Array<{ index: number }> = []
  for (let i = 0; i < amount; i++) {
    arr.push({
      index: i
    })
  }
  return arr
}

很容易。Rust实现类似:

#[wasm_bindgen]
pub fn create_rust_objects(amount: usize) -> JsValue {
    let mut arr: Vec<Obj> = vec![];
    arr.reserve(amount);

    for i in 0..amount {
        let itm = Obj { index: i };
        arr.push(itm);
    }

    JsValue::from_serde(&arr).unwrap()
}

我也尝试过使用哈希映射向量:

let mut field = HashMap::new();
field.insert("index", i);
arr.push(field);

两者“速度”一样慢。

我使用随 wasm-build 提供的 js 和 d.ts 文件导入了 Wasm 二进制文件。

JavaScript 至少比 Rust 代码快两倍。为什么会这样?我在实现上做错了什么吗?实现按照 MDN 文档设置。

我把所有的代码都放在一个 React 项目中 - https://github.com/Devalo/rust-react-wasm-test


2
只是好奇,你有没有测试过不使用 JsValue::from_serde(&arr).unwrap() 的速度? - Christian Fritz
这是一个好想法。我还没有做到,因为我一直在努力将 Rust 类型返回给 JavaScript。我在 Rust-Wasm 书中找到了 serde 相关的内容。 - Stephan Bakkelund Valois
2
请展示一下您如何测量速度。对于这样一个简单的函数来说,serde 的开销可能比对象创建代码本身还要高。 - Bergi
速度是通过JavaScript的性能API(performance.now())进行测量的。我也一直在思考同样的问题,由于V8引擎可能会对期望的极度优化的内容(如递增循环)进行优化,因此我尝试测量一些加密和区块链操作,以查看是否有所不同。 - Stephan Bakkelund Valois
这个回答解决了您的问题吗?为什么我的Rust程序比相应的Java程序慢? - Stargateur
1个回答

2
答案是您可能没有做错任何事情。基本上,WASM有潜力更快,但并非总是更快。
我真的很喜欢Winston Chen在 这篇文章 中所做的性能测试,比较了Web Assembly和Vanilla JS。
如果您对更深入的讨论感兴趣,Surma在Google I/O '19上的这个演讲非常有启发性。从视频中可以得知:

JavaScript和Web Assembly具有相同的最大性能。它们同样快。但是,与JavaScript相比,使用Web Assembly更容易保持高速状态。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接