I was looking for some micro optimizations of some JavaScript legacy code I was revisiting and noticed that in most frequently called for loops, counters were declared once in the global scope, outside the functions using them. I was curious whether that was indeed an optimization therefore I have created the following test case in JavaScript:
var tmp = 0;
function test(){
let j = 0;
function letItBe(){
for(j = 0; j < 1000; j++){
tmp = Math.pow(j, 2);
}
}
function letItNotBe(){
for(let l = 0; l < 1000; l++){
tmp = Math.pow(l, 2);
}
}
console.time("let it be");
for(var i =0; i < 10000; i++){
letItBe();
}
console.timeEnd("let it be");
console.time("let it not be");
for(var i =0; i < 10000; i++){
letItNotBe();
}
console.timeEnd("let it not be");
}
test();
What happens is that letItNotBe()
runs significantly faster than letItBe()
, in Chrome, Firefox and also NodeJS
NodeJS:
Changing let with var makes no difference.
Initally my logic was that declaring a new counter variable every time a function is called would be indeed slower than if a variable is initially declared and then simply reset to 0. However, it turns out to be quite the oposite and the difference in execution time is quite substential.
My simple explanation is that when the counter variable is declared ouside the function using it, in some way the JS transpiler needs to refer to this variable. And since it is in the parent scope it takes more executions to reference it when incrementing. However that's just blind guessing.
Can anybody give any meaningful explanation why this is happening, since I need to refactor the code and give a meaningful explanation mysefl besides the test that I already have :) Thanks.