Performance concern with let/const
lukeh at microsoft.com
Mon Sep 17 08:05:58 PDT 2012
From: Andreas Rossberg [mailto:rossberg at google.com]
> On 17 September 2012 03:35, Luke Hoban <lukeh at microsoft.com> wrote:
> > __Temporal dead zones__
> > As an experiment, I took the early-boyer test from V8 and changed 'var' to 'let'. In Chrome preview builds with 'let' support, I saw a consistent ~27% slowdown. That is, the 'let is the new var' mantra leads to 27% slower code in this example for the same functionality.
> Just to be clear, the V8 implementation of block scoping and 'let' has not seen any serious performance optimisation yet. So I'd take these numbers (which I haven't verified) with a large grain of salt.
Yes - sorry I didn't make this more clear. This baseline was relevant mostly because it motivated trying to gather data with some of the key optimizations implemented.
> Also, I conjecture that the main cost for 'let' isn't the temporal dead-zone, but block allocation. In particular, a 'let' in a loop costs a significant extra if no static analysis is performed that would allow hoisting the allocation out of the loop.
That may well be another significant perf concern. For early-boyer in particular, I believe the structure of the code ensures that this particular issue will not come into play - the code largely hoists variable declarations to top of function scope.
> > However, we are aware that there are a class of dynamic checks that can be removed by static analysis - in particular intra-procedural use before assignment checks. We implemented these checks in a Chakra prototype, and even with these, we still see an ~5% slowdown.
> I would like to understand this better. AFAICT, you don't necessarily need much static analysis. In most cases (accesses from within the same closure) the check can be trivially omitted.
Yes - this is what we implemented in the Chakra prototype. Though note that the 'switch' issue raised on the list recently leads to cases even within a closure body where static analysis is insufficient - such as this (though I would guess this case won't be the primary perf culprit):
return x; //always a runtime error
x = 'let'; //never a runtime error
return x; //sometimes a runtime error
} while (foo());
>> __ Early Errors__
>> This ultimately means that any script which mentions 'const' will defeat a significant aspect of deferred AST building, and therefore take a load time perf hit.
>This is indeed a concern. However, I don't think 'const' is the only problem, other ES6 features (such as modules) will probably introduce similar classes of early errors.
Agreed - this concern is broader 'let'/'const'.
>> More generally - this raises a concern about putting increasingly more aggressive static analysis in early errors. It may, for example, argue for a 3rd error category, of errors that must be reported before any code in their function body executes.
> I agree that this is a worthwhile possibility to consider. I mentioned this idea to Dave once and he didn't like it much, but maybe we should have a discussion.
More information about the es-discuss