Búsqueda de sitios web

javascript - ¿Por qué let es mucho más lento después de un bucle for que antes de un bucle for?


En node.js v6.0.0

function testlet() {
	let a = 0;
	for (var i = 0; i < 100000000; i++) {}
}

function testlet2() {
	for (var i = 0; i < 100000000; i++) {}
	let a = 0;
}

console.time('let');
testlet();
console.timeEnd('let'); 

console.time('let2');
testlet2();
console.timeEnd('let2'); 

¿Cómo puede la posición de let en el código causar una diferencia de rendimiento tan grande?

Respuesta #1

Haré una suposición educada y diré que la zona muerta temporal es la culpable.

Ese bucle, que parece ser de lo que trata tu microbenchmark, es devorado por el optimizador en el desayuno, como a Vyacheslav Egorov le gusta decirlo en sus charlas. Y aun si no lo es y el motor incrementa una variable un millón de veces, tomará el mismo tiempo en ambas funciones.

Lo que es diferente es cuándo se crea la variable a. En tu primer fragmento, está al principio de la función, no hay nada antes de ella. No hay zona muerta temporal, es esencialmente una variable de alcance de función; cambiarla a un var no haría ninguna diferencia (pruébalo). Así que cuando se invoca la función, se crea el alcance con la variable y el valor se inicializa en 0, luego algún código se ejecuta (o no).
En contraste, en el segundo fragmento hay una zona muerta temporal. En el código que precede a la declaración del let, acceder a a debe lanzar una excepción. Así que cuando se invoca la función, se crea el alcance y se reserva un espacio para a pero se deja sin inicializar. En este estado, el código se ejecuta (o no), y solo después de eso la variable se inicializará y se le asignará el valor 0.

Entonces, si el let está en medio del código (o después de este), el alcance es más complejo. Esto podría hacer que el optimizador lo trate de manera diferente, tal vez incluso afectar a la variable i que está en el mismo ámbito, o posiblemente no poder realizar ciertas optimizaciones en absoluto.