Performance concern with let/const

Allen Wirfs-Brock allen at wirfs-brock.com
Mon Sep 17 07:09:32 PDT 2012


some comments below

On Sep 16, 2012, at 9:35 PM, Luke Hoban wrote:

> We've begun deeper investigations of implementation practicalities related to let/const, and two significant performance concerns have been raised.  I think these both merit re-opening discussion of two aspects of the let/const design.
> 
> 
> __Temporal dead zones__
> 
> For reference on previous discussion of temporal dead zone see [1].
> 
> I've expressed concerns with the performance overhead required for temporal dead zones in the past, but we did not at the time have any data to point to regarding the scale of the concern.  
> 
> 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.  

Without evaluating the quality of the Chrome implementation, this isn't a meaningful observation.  As the Chrome implements have stated they have not done any optimization, this actually becomes a misleading statement.  You really should just strike this assertion from your argument and start with your actual experiments as the evidence  to support your position.


> 
> 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.  
> 
> Our belief is that any further removal of these dynamic checks (inter-procedural checks of accesses to closure captured let references) is a much more difficult proposition, if even possible in any reasonable percentage of cases.  

To understand the general applicability of this results  we need to know what specific static optimizations you performed and evaluate that against the list of plausible optimizations.  I'd also like to understand that the specific coding patterns within the test program could not be statically optimized.

It's great to use experimental results to support you point, but the result needs to be possible to independently validate and analyze the results.

> 
> Unless we can be sure that the above perf hit can indeed be easily overcome, I'd like to re-recommend that temporal dead zones for let and const be removed from the ES6 specification.  Both would remain block scoped binding, but would be dynamically observable in 'undefined' state - including that 'const' would be observable as 'undefined' before single assignment.  

We really don't have enough evidence to come to that conclusion

> 
> In particular - the case against temporal dead zones is as follows:
> 
> 1. The value of temporal dead zones is to catch a class of programmer errors.  This value is not overly significant (it's far from the most common error that lint-like tools catch today, or that affects large code bases in practice), and I do not believe the need/demand for runtime-enforced protection against this class of errors has been proven.  This feature of let/const is not the primary motivation for either feature (block scoped binding, inlinability and errors on re-assignment to const are the motivating features).

As far as I'm concerned the motivating feature for TDZs is to provide a rational semantics for const.  There was significant technical discussion of that topic and TDZs emerged as the best solution. An alternative argument you could make would be to eliminate const.  Is there a reason you aren't making that argument?
> 
> 2. The stated goal of 'let' is to replace 'var' in common usage (and if this is not the goal, we should not be adding 'let'). 

There is actually some disagreement about that statement of the goal.  The goal of let is to provide variable that are scoped to the block level.  That is the significant new semantics that is being added.  The slogan-ism isn't the goal.

As stated above, let isn't the motivator for TDZ, it's const.   Let could easily be redefined to not need a TDZ (if that really proved to be a major area of concern).  So, you either need to argument against const or argue against block scoping, in general rather let.

> 
> 3. Unless the above performance hit can be overcome, and given #2 above, *let will slow down the web by ~5%*.

As covered above, this is a bogus assertion without data to support it.

> 
> 4. Even if the above performance hit can be (mostly) overcome with net new engine performance work, that is performance work being forced on engine vendors simply to not make the web slower, and comes at the opportunity cost of actually working on making the web *faster*.  

Again, isn't this really a question about the value of const.
> 
> 5. We are fairly confident that it is not possible to fully remove the runtime overhead cost associated with temporal dead zones.  That means that, as a rule, 'let' will be slower than 'var'.   And possibly significantly slower in certain coding patterns. Even if that's only 1% slower, I don't think we're going to convince the world to use 'let' if it's primary impact on their code is to make it slower.  (The net value proposition for let simply isn't strong enough to justify this).

I think you an fairly easily prove that there are use cases where the TDZ can not be statically eliminated  But that does not man that on average and for a typical program "let will be slower than var".

Again, you might be better served to argue that block level lexical scoping is slower than a single contour function level scoping. However, that's an argument that's a forty year old argument that really should have to be reopenned.

> 
> 6. The only time-proven implementation of let/const (SpiderMonkey) did not implement temporal dead zones.  The impact of this feature on the practical performance of the web is not well enough understood relative to the value proposition of temporal dead zones.

And it has a pretty bogus semantics for const.  But generally this isn't relevant as FF let/const can not be interoperably used on the web so it doesn't tell us much about the practical perf of the web. 

> 
> 
> __ Early Errors__
> 
> Let and const introduce a few new early errors (though this general concern impacts several other areas of ES6 as well).  Of particular note, assignment to const and re-declaration of 'let' are spec'd as early errors. 
> 
> Assignment to const is meaningfully different than previous early errors, because detecting it requires binding references *before any code runs*.  Chakra today parses the whole script input to report syntax errors, but avoids building and storing ASTs until function bodies are executed [2].  Since it is common for significant amounts of script on typical pages to be downloaded but not ever executed, this can save significant load time performance cost.  
> 
> However, if scope chains and variable reference binding for all scopes in the file need to be established before any code executes, significantly more work is required during this load period.  This work cannot be deferred (and potentially avoided entirely if the code is not called), because early errors must be identified before any code executes.
> 
> 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.  
> 
> 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.  But more likely, it just argues for allowing any heavy static analysis to be postponed to late errors (or removed entirely and left to lint tools, if the raw overhead is particularly significant).

I think you may have a stronger point, if this is really the actual basis of your concern. Perhaps there is call for a 3rd category of errors, that can be differed beyond initial parse.  However, I think const is probably the least of your concerns in this regard.  It would be useful to get deeper into what other semantics we are considering have impact on deferred AST construction.

Allen












> 
> 
> Luke
> 
> [1] https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html
> [2] http://blogs.msdn.com/b/ie/archive/2012/06/13/advances-in-javascript-performance-in-ie10-and-windows-8.aspx
> 
> 
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
> 



More information about the es-discuss mailing list