在对wasm进行一些实验的过程中,我发现我的手编wasm比它的jsalternative多花2倍的时间,这与 i32.rem_s
操作。
(module
(func $add (param $p1 i32)
(result i32)
(local $i i32) (local $s i32)
(local.set $i (local.get $p1))
(local.set $s (i32.const 0))
loop $while
(i32.add (local.get $i) (local.get $s))
(i32.rem_s (i32.const 1000007))
local.set $s
(i32.add (local.get $i) (i32.const -1))
local.set $i
(i32.ne (i32.const 0) (local.get $i))
br_if $while
end
local.get $s
)
(export "add" (func $add))
)
import { add } from "./add.wasm";
const n = 100000000;
const x = new Date;
console.log(add(n));
console.log(new Date - x);
const y = new Date;
let s = 0;
for (let i = n; i > 0; i -= 1) {
s = (s + i) % 1000007;
}
console.log(s);
console.log(new Date - y);
244650
892
244650
483
问题出在哪里?我手写的汇编没有优化?JS有很智能的优化?还是V8的wasm runner的bug?
我是在我的Ubuntu上用intel corei7运行的,重要的话用nodejs v14.2.0。
你进行了我所说的 "微基准",即一段很小的代码,使用了有限的指令,被反复执行了很多次。这种基准测试的技术是非常不准确的!
是的,JavaScript一旦经过优化,就可以达到接近原生的性能。
你比较的是完全不同的操作--JavaScript的数字都是浮点运算,而WebAssembly则使用32位整数。