
Show HN: Faster.js – a micro-optimizing JavaScript compiler - vzhou842
https://github.com/vzhou842/faster.js
======
joshwcomeau
This is cool, but array methods are so rarely the bottleneck; Even in the
highly-specialized demo, the difference is near-negligible.

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)

~~~
rococode
I agree, while this is a cool idea it doesn't seem to be useful beyond being a
proof of concept of an optimization technique. For example, my browser
rendered the faster.js version 50ms slower at this point:
[https://i.imgur.com/G5b10Ns.jpg](https://i.imgur.com/G5b10Ns.jpg). It does
appear to perform better in the long run
([https://i.imgur.com/u3ApYYl.jpg](https://i.imgur.com/u3ApYYl.jpg)) but it's
an improvement of less than 1%, and when your renders are taking 30+ms there
are probably other things you should be looking at :P

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.

------
partycoder
Optimizing JavaScript is hard.

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://en.wikipedia.org/wiki/Inline_caching)

\-
[https://static.googleusercontent.com/media/research.google.c...](https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/43823.pdf)

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.

------
RubenSandwich
Prepack, [https://prepack.io](https://prepack.io), is also in the same realm
of an optimizing Javascript compiler.

~~~
k__
Prepack is rather nice. It allows you to execute part of your code at compile
time, like a macro.

~~~
leeoniya
Closure compiler in ADVANCED_OPTIMIZATIONS mode does this too.

    
    
        function add5(x) {
          return x + 5;
        }
    
        console.log(add5(3));
    

compiles down to

    
    
        console.log(8);

~~~
danabramov
Prepack is doing much more than GCC can because it effectively evaluates the
whole code and then serialises its heap. This is both its biggest strength and
weakness.

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).

~~~
yoklov
I would avoid using the name GCC to refer to the closure compiler, since
there's already an extremely well-known compiler named GCC.

Admittedly it doesn't take JS as input, but I was somewhat confused when I
read your comment nonetheless.

------
ronaldj
On the demo page in Chrome, Faster.js is actually slower.

~~~
Zekio
For me faster.js was faster for 2 seconds then it became slower and slower in
Firefox

~~~
k__
faster.js was about 9ms faster on my mobile device.

------
sharpercoder
I'd like to be able to specify restrictions on type usage in Javascript. For
instance, in some cases I know that my array will always be 6 items larges -
no smaller, no larger, never sparse. But I can't specify this, yet it allows
for certain optimizations (e.g. loop unrolling).

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.

------
qwermike
Probably, you can optimize .forEach even more. You can get 'arr.length' and
'let i = 0' outside of the for-loop.

It could be faster according to this test: [https://jsperf.com/extended-array-
loops-performance](https://jsperf.com/extended-array-loops-performance)

------
royjacobs
Why is this called a "compiler", though?

------
Ihfhcub
Their first example

for (let _i = 0; _i < arr.length; _i++) { results.push(_f(arr[_i], _i, arr));
}

This is recalculating length on each iteration

~~~
hajile
The mystery of JIT optimization. The optimizer will turn that into a
dereferenced register value. I remember reading that v8 used to add an extra
instruction if you assigned the variable yourself.

------
tlrobinson
Are you using this in a real application?

~~~
vzhou842
I've been trying it out in prod on a small site I run:
[http://geoarena.online](http://geoarena.online)

------
abritinthebay
The demo page basically shows this is pointless practically - and sometimes
_slower_.

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.

------
_blrj
I thought I was in new and not the front page. You're telling me that as a
demonstration of perf gains, in a graphics context I win back .8 ms in
exchange for another dependency and unnecessary cognitive load?

------
elka
This is a good example of premature optimization.

~~~
cprecioso
I think this is an example of _optimization_. An optimization that is easily
applied as a transform for Babel, but that's just it.

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?

~~~
elka
The optimization is transforming all code that matches the pattern independent
from whether the code is hot or not.

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.

