Hacker News new | ask | show | jobs
by titzer 2986 days 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.

3 comments

If it's nearly impossible to defeat inlining, wouldn't the appropriate comparison be against inlined JS?
You 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...

For v8, doesn’t a try/catch block defeat inlining? It used to, but that was a long time ago.
No, not with TurboFan (since Q2 2017).