Javascript var vs let (de) optimización / desaceleración en v8 y SpiderMonkey

Durante la refactorización de código JavaScript en mi proyecto, he encontrado que algunos de mis bucles se ralentizaron drásticamente. Buscando la causa raíz, encontré esta pregunta SO que indica que la desaceleración está causada por la instrucción let interior for creación de bucle y cierre. Para mi sorpresa, mover y cerrar fuera del bucle for no ayudó, e incluso usar var lugar de let que la variable bucle for tampoco ayuda porque la desaceleración se debe a let coloca después del bucle for . Al eliminar detalles adicionales, he obtenido este fragmento de código:

 "use strict" console.log("========================="); (function(){ var itr = 0; function f(){++itr;} console.time('without_let'); for(var i = 0; i < 50000000; ++i){ f(); } var totals = 0; console.timeEnd('without_let'); //chrome: 122ms, FF:102ms })(); (function(){ var itr = 0; function f(){++itr;} console.time('let_below'); for(var i = 0; i < 50000000; ++i){ f(); } let totals = 0; // <--- notice let instead of var console.timeEnd('let_below'); //chrome: 411ms, FF:99ms })(); (function(){ let itr = 0; function f(){++itr;} console.time('let_above_and_in_loop'); for(let i = 0; i < 50000000; ++i){ f(); } var totals = 0; console.timeEnd('let_above_and_in_loop'); //chrome: 153ms, FF:899ms })(); (function(){ var itr = 0; function f(){++itr;} console.time('let_in_loop'); for(let i = 0; i < 50000000; ++i){ f(); } var totals = 0; console.timeEnd('let_in_loop'); //chrome: 137ms, FF:102ms })(); 

(también en JS Fiddle Note: el uso de JS Fiddle muestra resultados poco diferentes pero una desaceleración similar todavía está presente en los mismos lugares)

Ejecutando esto en Chrome produce los siguientes

  without_let: 122ms let_below: 411ms <----------- Slowdown for v8 let_above_and_in_loop: 153ms let_in_loop: 137ms 

¡Algunas búsquedas en Google me llevaron al artículo que decía que let desoptimización antes de Chrome 56 / V8 5.6! pero mi cromo es 57.0.2987.133 (64 bits) y v8 ver 5.7.492.71. Más sorpresas al intentar ejecutar esto en Firefox 52.0.2 (32 bits). Aquí tenemos la desaceleración en otro lugar, cuando la variable creada con let se usa dentro del cierre:

  without_let: 101.9ms let_below: 99ms let_above_and_in_loop: 899ms <----- Slowdown for SpiderMonkey let_in_loop: 102ms 

Como veo, el problema está algo relacionado con la característica llamada “Zona Muerta Temporal”, pero aún no está claro:

  1. ¿Por qué dos navegadores principales (los principales motores de JavaScript) aún no pueden optimizar esas partes (diferentes) del fragmento?

  2. ¿Hay soluciones alternativas para seguir usando let ( excepto el uso de Babel para convertir let en var)? Supongamos que puedo pasar opciones a Chrome o incluso directamente a v8 a través de v8::V8::SetFlagsFromCommandLine(&argc, argv, true);

UPD: En Chrome ver 58.0.3029.96, correspondng v8 versión 5.8.283.37 (según https://omahaproxy.appspot.com/ ) después de habilitar chrome: // flags / # enable-v8-future como jmrk se sugiere a continuación. desaceleración para el tercer caso (ahora 2 veces en lugar de 8 veces)

 without_let: 157.000ms let_below: 155.000ms let_above_and_in_loop: 304.000ms let_in_loop: 201.000ms 

Firefox 53.0 (32 bits)

 without_let: 278.650ms let_below: 310.290ms let_above_and_in_loop: 848.325ms let_in_loop: 275.495ms 

One Solution collect form web for “Javascript var vs let (de) optimización / desaceleración en v8 y SpiderMonkey”

Puedo responder la parte V8 de la pregunta. La desaceleración que está viendo se debe a una limitación en el antiguo comstackdor de optimización (conocido como “Cigüeñal”). No se ha abordado en todo este tiempo porque el equipo ha estado ocupado trabajando en el nuevo comstackdor de optimización (“Turbofan”), que se está enviando en Chrome 59 (actualmente en los canales Canary y Dev, ¡pronto en Beta!).

En Chrome 58 (actualmente en Beta), ya puede obtener una vista previa configurando el “Canal de comstackción experimental de JavaScript” en “Habilitado” (en chrome://flags/#enable-v8-future ). Tenga en cuenta que Chrome 59 tendrá un par de mejoras de rendimiento adicionales.

Nota al margen: en una base de código existente, no hay mucho beneficio en migrar que let , así que puedes seguir usando var .

  • La mejor manera de ejecutar Narwhal en Linux
  • Utilice el motor V8 JavaScript para ejecutar JS lib sin webview
  • Comstackr JavaScript a código nativo con V8
  • File System I / O en Javascript usando V8
  • ¿Muestra todos los methods de objects en una list en la console de Chrome?
  • ¿Por qué la recursión "requestAnimationFrame" no consumirá RAM?
  • Crear un object dos veces produce resultados diferentes
  • Ejecutando V8 Javascript Engine Standalone
  • ¿hay alguna solución para el analizador de dates v8 roto?
  • ¿Cómo emular el object "window" en Nodejs?
  • ¿Qué sucede con el código de estado v8 en la optimization / ejecución de la function?
  • Javascript tiene muchos buenos JS marco (como Node.js AngularJS Vue.js React.js) es el mejor lenguaje de script.