I'd like to know the reason why these two codes run at different speeds.
fast.js
var N = 2e9;
(function () {
console.time();
var count = 0;
for (var i = 0; i < N; i++) count++;
if(false) console.log(count);
console.timeEnd()
})();
slow.js
var N = 2e9;
(function () {
console.time();
var count = 0;
for (var i = 0; i < N; i++) count++;
if(false) (() => console.log(count));
console.timeEnd()
})();
Execution
% node fast.js
default: 1.297s
% node slow.js
default: 3.175s
The difference between the codes is line 6.
if(false) console.log(count);
if(false) (() => console.log(count));
But these parts never run because it's dead code.
@tkihira analyzed and concluded that variable count was allocated in heap because it's used in closure when slow.js ran so that it took more time to increment it in the for loop. While count in fast.js is in a register.
This made the speed difference.
Does anyone know which part of the code in V8 makes this behavior? Is it true that a number variable is allocated in heap when it's used in a closure that never runs and a variable and it's in a register when it's not used in a closure?
Analytics by @tkihira: source code: https://gist.github.com/tkihira/b9c7fe8c31e21f1022011e377f7e672d
jit output: https://gist.github.com/tkihira/67a07231cc6a4ce55462d8cdfa51a6e2
diff: https://gist.github.com/tkihira/5f5877cde581c66cae3bc02f88e505e4
twitter thread: https://twitter.com/tkihira/status/1365280241195782149