He observado un comportamiento extraño de los trabajadores web. Suponga que worker.js contiene el siguiente código
onmessage = function(event) { var x = event.data; var c = 0; for(var i = 0; i < x; i++) c = c + Math.random(); postMessage(c); }Creo y trabajo, publico "100000000" en él, para ejecutarlo durante 100 millones de bucles. Tarda alrededor de 900 milisegundos.
Ahora, considere el mismo código, sin un evento onmessage. Se ejecutará inmediatamente después de crearse, sin tener que activarlo a través de postMessage.
var x = 100000000; var c = 0; for(var i = 0; i < x; i++) c = c + Math.random(); postMessage(c);Los mismos 100 millones de bucles, pero esta vez tarda un promedio de 2200 milisegundos. Más del doble.
¿Hay alguna explicación para esta brecha de rendimiento? ¿Un problema de compilación quizás?
Actualice , según lo solicitado, así es como se mide el rendimiento:
var worker = new Worker('worker.js'); var time = performance.now(); worker.onmessage = function(event) { time = performance.now() - time; }Desarrollador V8 aquí.
Lo que sucede aquí es que acceder (en particular: escribir en) variables globales es más lento que acceder a variables locales de funciones, principalmente porque el código optimizado puede mantener estas últimas en los registros, pero no las primeras.
Esto no es un error, no está relacionado con los trabajadores, y todo se está optimizando.
Afortunadamente, el código del mundo real casi nunca tiene código caliente en el nivel superior, por lo que esto es en su mayoría solo otro artefacto de microbenchmarking.
Ejemplo reducido:
(function fast() { var x = 100000000; const t1 = performance.now(); for (var i = 0; i < x; i++) {}; // i is local const t2 = performance.now(); console.log("fast", t2 - t1); })(); (function slow() { var x = 100000000; const t1 = performance.now(); for (i = 0; i < x; i++) {}; // oops, forgot `var`, i is global const t2 = performance.now(); console.log("slow", t2 - t1); })(); Poner el código en el ámbito de nivel superior es otra variante de function slow , porque todas las variables son variables globales allí.