Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decreased performance in code running in Temporal Dead Zone #12568

Closed
mitsos1os opened this issue Apr 21, 2017 · 6 comments
Closed

Decreased performance in code running in Temporal Dead Zone #12568

mitsos1os opened this issue Apr 21, 2017 · 6 comments
Labels
performance Issues and PRs related to the performance of Node.js. question Issues that look for answers. v8 engine Issues and PRs related to the V8 dependency.

Comments

@mitsos1os
Copy link
Contributor

  • 7.9.0:
  • Linux mitsos-XPS-13-9360 4.10.0-19-generic add issue contributing section #21~16.04.1-Ubuntu SMP Fri Apr 7 08:20:02 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux:
  • Subsystem:

**I have created a detailed Stack Overflow question here so I will quote it here to get some answers since I do not know the internal mechanichs...

Quoted Question:

I have noticed in an other question the performance difference in loops while using let and var variables declaration.

The initial question is correctly answered that using let in the for loop is slower since let creates a new scope for each iteration to hold the value of let declared variable. More work to be done, so it is normal to be slower. Just as reference, I give the code and the results in NodeJS (7.9.0) execution time:

Please note that all javascript code below regards NodeJS version 7.9.0

Regular Code:

'use strict';
console.time('var');
for (var i = 0; i < 100000000; i++) {}
console.timeEnd('var');


console.time('let');
for (let j = 0; j < 100000000; j++) {}
console.timeEnd('let');

Output:

var: 55.792ms
let: 247.123ms

In order to avoid the extra scope declaration for j in every iteration of the loop, we declare the j variable just before the loop. One would expect that this should now make the let loop performance match the one of var. BUT NO!!! This is the code and the result for reference:

Code with let defined before loop:

'use strict';
console.time('var');
for (var i = 0; i < 100000000; i++) {}
console.timeEnd('var');


console.time('let');
let j;
for (j = 0; j < 100000000; j++) {}
console.timeEnd('let');

Output:

var: 231.249ms
let: 233.485ms

We can see that, not only the let loop did not get any faster but also the var loop became as slow as the let one!!! The only explanation for this is that since we are not in any block or function, both variables are declared in the global module scope. However as referenced here, the let declaration of the variable in the middle of the scope, creates a temporal dead zone, which leaves the variable j uninitialized, while the var initializes the variable as defined.

So running code in a temporal dead zone although the uninitialized variable is not referenced, must be quite slower....

Finally to show the deference, we declare the j variable on top of the program to show the results of running it without the temporal dead zone.

Code without temporal dead zone:

'use strict';
let j;
console.time('var');
for (var i = 0; i < 100000000; i++) {}
console.timeEnd('var');


console.time('let');
for (j = 0; j < 100000000; j++) {}
console.timeEnd('let');

Output:

var: 55.586ms
let: 55.009ms

Now both let and var loops have similar optimized performance!

Does anyone know whether my assumption about temporal dead zone performance is correct, or provide a different explanation???

@vsemozhetbyt vsemozhetbyt added performance Issues and PRs related to the performance of Node.js. question Issues that look for answers. v8 engine Issues and PRs related to the V8 dependency. labels Apr 21, 2017
@vsemozhetbyt
Copy link
Contributor

cc @nodejs/performance @nodejs/v8

@peterwmwong
Copy link
Contributor

Maybe @caitp has already fixed this with... v8/v8@267115d

Benchmarks: v8/v8@e2670e8

@caitp
Copy link
Contributor

caitp commented Apr 21, 2017

That fix should lead to improved perf (matching or beating var), in specific conditions:

  1. loop variable is not captured by closure or eval (can still be passed to functions)

  2. does not occur in a generator or async functions or top level Module code (this could be improved later).

In the other cases, even the opt case seems to do worse than the opt case in var loops, so there's more work to do still.

@simonkcleung
Copy link

Relate to http://stackoverflow.com/questions/37792934/why-is-let-slower-than-var-in-a-for-loop-in-nodejs

I suggest using let only when you need closure of the variable.

@Trott
Copy link
Member

Trott commented Aug 2, 2017

I'm getting similar results with Node.js 8.2.1 but radically different results with the master branch which has V8 6.0 currently (and which will come out in Node.js 8.3.0 Very Soon Now).

Is this resolved in V8 6.0?

(Since this is a V8 issue, should this issue remain open in this repository?)

@targos
Copy link
Member

targos commented Aug 3, 2017

I tested with 8.3.0-rc.0 and the speed is the same in all cases. I think we can consider this as resolved by the V8 6.0 upgrade.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Issues and PRs related to the performance of Node.js. question Issues that look for answers. v8 engine Issues and PRs related to the V8 dependency.
Projects
None yet
Development

No branches or pull requests

7 participants