3 ms·
The cost is more than a JS->JS call, but not drastically so. Every argument must be converted from a number to an int32/float32/float64, which for SMI values is
by titzer 9y ago
The cost is more than a JS->JS call, but not drastically so. Every argument must be converted from a number to an int32/float32/float64, which for SMI values is a single branch, for heap numbers a branch and a load. For other JS values, a ValueOf() operation on the JS value.
V8 generates little wrappers for these, with inline conversions. It does not currently inline the little wrapper functions, nor use ICs for the conversions inside, since branches are generally enough to get the interesting fast cases.
The idea of a super-expensive call is therefore a bit of a myth. You can try to measure the cost yourself, but be careful! Most microbenchmarks will end up comparing the difference between an inlined JS call (as low as zero overhead) versus a non-inlined WASM->JS or JS->WASM call. The proper comparison would be instead with a non-inlined JS->JS call. Defeating inlining for JS->JS calls is tricky. You can do it with cross-realm calls, or by trying manipulating polymorphism. In either case, it's pretty tricky, so good luck.
- girvo 9y agoFor v8, doesn’t a try/catch block defeat inlining? It used to, but that was a long time ago.
- titzer 9y agoNo, not with TurboFan (since Q2 2017).
- colordrops 9y agoIf it's nearly impossible to defeat inlining, wouldn't the appropriate comparison be against inlined JS?
- pygy_ 9y agoYou can defeat inlining by using closures: function thunk(x){ return function() { x() } } const thunkFoo = thunk(foo) const thunkBar = thunk(bar) for(var i = 0; i < 10000; i++) { thunkFoo() thunkBar() } This is why the "Maybe you don't need Rust to speed up your JS" author was creating functions dynamically using `new Function()`. Maybe you cal get away with function call(x){ x() } for(var i = 0; i < 10000; i++) { call(foo) call(bar) } I didn't test the latter though, whereas the former is empirically slower if you call more than one thunk in your benckmark loop (a single thunk will have the call inlined). https://mrale.ph/blog/2018/02/03/maybe-you-dont-need-rust-to-speed-up-your-js.html https://mrale.ph/blog/2018/02/03/maybe-you-dont-need-rust-to...