为什么将 DOM 对象作为“exnternref”传递比通过 JS 值表传递“慢”?

Yuj*_*oto 8 rust webassembly wasm-bindgen

exnternref我制定了一个基准测试,通过将 DOM 对象作为s 传递给 Wasm 函数来衡量调用 DOM API 的速度。这是要测量的函数(用 Rust 编写并由 rustc 1.55.0 编译):

#[wasm_bindgen]
pub fn append_and_remove(elem: web_sys::Element) {
    let doc = web_sys::window().unwrap().document().unwrap();
    let child = &doc.create_element("br").unwrap();
    elem.append_with_node_1(child).unwrap();
    let _ = elem.remove_child(child).unwrap();
}
Run Code Online (Sandbox Code Playgroud)

(完整代码请参见https://github.com/igrep/wasm-reference-types-examples )

我比较了两个 Wasm 模块(及其 JS 包装器)和等效的 JavaScript 代码:一个(“带引用类型”版本)使用 进行预处理wasm-bindgen --reference-types,另一个(“无引用类型”版本)仅使用 进行预处理wasm-bindgen

这是运行一百万次的结果:

浏览器 标签 时间(毫秒)
火狐94.0.1 无参考类型 2167
带参考类型 2687
仅 JavaScript 第637章
铬95.0.4638.69 无参考类型 3432
带参考类型 4129
仅 JavaScript 1039
边缘95.0.1020.44 无参考类型 3416
带参考类型 3858
仅 JavaScript 第1187章

(两个浏览器都是64位版本,在Windows 10上)

根据上面的结果,在三个浏览器中,“无引用类型”版本比“有引用类型”版本快约 20%。尽管“有引用类型”版本被较小的 JavaScript 包装,但为什么它会被“无引用类型”版本击败?引用类型引入了哪些开销?