Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Reminds me of this comment by Petka Antonov on native V8 Promises being way slower than Bluebird[1]:

>I'd expect native browser methods to be an order of magnitude faster.

Built-ins need to adhere to ridiculous semantic complexity which only gets worse as more features get added into the language. The spec is ruthless in that it doesn't leave any case as "undefined behavior" - what happens when you use splice on an array that has an indexed getter that calls Object.observe on the array while the splice is looping?

If you implemented your own splice, then you probably wouldn't even think of supporting holed arrays, observable arrays, arrays with funky setters/getters and so on. Your splice would not behave well in these cases but that's ok because you can just document that. Additionally, since you pretty much never need the return value of splice, you can just not return anything instead of allocating a wasted array every time (you could also make this controllable from a parameter if needed).

Already with the above, you could probably reach the perf of "native splice" without even considering the fact that user code is actually optimized and compiled into native code. And when you consider that, you are way past any "native" except when it comes to special snowflakes like charCodeAt, the math functions and such.

Thirdly, built-ins are not magic that avoid doing any work, they are normal code implemented by humans. This is biggest reason for the perf difference specifically in the promise case - bluebird is extremely carefully optimized and tuned to V8 optimizing compiler expectations whereas the V8 promise implementation[2] is looking like it's directly translated from the spec pseudo-code, as in there is no optimization effort at all.

[1]: https://github.com/angular/angular.js/issues/6697#issuecomme...

[2]: https://github.com/v8/v8/blob/master/src/promise.js



His "optimization killers" article is also really insightful: https://github.com/petkaantonov/bluebird/wiki/Optimization-k...


> Additionally, since you pretty much never need the return value of splice, you can just not return anything instead of allocating a wasted array every time

That kind of optimization seems easily done with a builtin as well: have an option to return the array, and only do so if the JavaScript engine indicates that the calling code actually uses the return value.


That seems like something well suited to compile-to-js languages like Coffeescript. It could substitute cases as you mentioned with fast.js equivalent functions.


CoffeeScript inserts calls to native `indexOf` all over the place. After seeing this I'm wondering if there's an easy way to shim fast.js in there?


This itself reminds me of similar performance issues hidden in C++. The float->int cast on x86 with Microsoft's compiler called a helper library function 'ftol'. Turns out this does loads of stuff to be spec compliant. Replacing it with a single not-spec-but-works-for-us x86 assembly instruction to convert was way faster.

So not just JS - it seems language built-ins are often slowed down by bureaucratic spec compliance, and hand-rolling code can help you get a speedup.


Specialisation in JavaScript JITs make these faster, since they don't even compile in that supporting code.

Whereas the builtin ones implemented in C++ do keep all the code in there.

This is why even full implementations written in JavaScript can be faster than C++.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: