Show HN: Faster.js – a micro-optimizing JavaScript compiler
github.com
github.com
It's a fun project and might have application in specialized situations (and maybe for Node, where time spent in synchronous iteration blocks all other requests?). But I feel like this does more harm than good in most cases (larger bundle, extra build step, less readable output code can make debugging harder, etc)
Also, unless I'm misunderstanding the README, using the plugin introduces the huge caveat of breaking code that uses "restricted names" (certain names of Array functions) - the example given is a class that defines a map() function, which apparently would cause some kind of failure. In larger codebases where you don't control all code used in production this seems like a big problem.
My main motivation for building this was to make a better way to use an optimization library like fast.js (https://github.com/codemix/fast.js), which inspired faster.js. A huge issue with the fast.js library is that you have to rewrite your entire codebase in order to use it, whereas enabling or disabling faster.js is a one line change.
The performance gap between a `for` loop and and a `.forEach` (also map) is much narrower than it used to be, and that is very encouraging.
v8 for instance, has the interpreter (ignition), and optimizing compiler (turbofan), that have a lot of undocumented behavior that people just to try to probe via microbenchmarks.
- https://en.wikipedia.org/wiki/Inline_caching
- https://static.googleusercontent.com/media/research.google.c...
If you want to understand what is going on the only way is to read v8's source code or running a profiler.
For example, did you know that touching the prototype of a RegExp object makes it slow? You had no way of knowing that.
Of course prepack also isn't even close to production ready yet either.
function add5(x) {
return x + 5;
}
console.log(add5(3));
compiles down to console.log(8);Unlike GCC, it can unroll any kind of metaprogramming, but it needs to have a model of the environment (e.g. it won’t execute code relying on DOM) and it can produce larger code (in terms of absolute size).
Admittedly it doesn't take JS as input, but I was somewhat confused when I read your comment nonetheless.
Also if you need faster numeric calculations https://github.com/non/spire (has scala.js support)
Lately I was memory profiling an application in Javascript using Chrome. The fact that it used ES6 classes really helped, as some anonymous classes where hard to find memory leaks with, but the typed classes was a simple text query.
I can imagine ES6 classes with decorators may enable specialized optimizations too.
It could be faster according to this test: https://jsperf.com/extended-array-loops-performance
for (let _i = 0; _i < arr.length; _i++) { results.push(_f(arr[_i], _i, arr)); }
This is recalculating length on each iteration
These kind of optimizations were very useful in hot paths even just a few years ago. However browser engines have optimized functional patterns (what this mostly rewrites) to be within absolute microseconds of imperative versions.
In some cases it can even make useful assumptions in an FP method (immutability, etc) that it can't in the standard loops - which is why sometimes this is slower.
Long story short: concentrate on shipping less JavaScript and good practical solutions/algorithms and not stuff like this.
Whether it is premature or not, it would depend on if you apply it carelessly without knowing whether you need it, or if you apply it when you know you need. Right?
The transformation comes with cognitive cost for the developer as it can turn correct code into incorrect code (sparse arrays).
By enabling this one trades complexity for potential performance gains.
This is how I understand premature.