2010-04-20 16 views
6

Estaba tratando de comparar la ganancia/pérdida de "caching" math.floor, con la esperanza de poder hacer las llamadas más rápido.Las variables locales tardan 7 veces más en acceder que las variables globales?

Aquí era la prueba:

<html> 
<head> 
<script> 
window.onload = function() 
{ 
    var startTime = new Date().getTime(); 
    var k = 0; 
    for(var i = 0; i < 1000000; i++) k += Math.floor(9.99); 
    var mathFloorTime = new Date().getTime() - startTime; 

    startTime = new Date().getTime(); 
    window.mfloor = Math.floor; 
    k = 0; 
    for(var i = 0; i < 1000000; i++) k += window.mfloor(9.99); 
    var globalFloorTime = new Date().getTime() - startTime; 

    startTime = new Date().getTime(); 
    var mfloor = Math.floor; 
    k = 0; 
    for(var i = 0; i < 1000000; i++) k += mfloor(9.99); 
    var localFloorTime = new Date().getTime() - startTime; 

    document.getElementById("MathResult").innerHTML = mathFloorTime; 
    document.getElementById("globalResult").innerHTML = globalFloorTime; 
    document.getElementById("localResult").innerHTML = localFloorTime; 
}; 
</script> 
</head> 
<body> 
Math.floor: <span id="MathResult"></span>ms <br /> 
var mathfloor: <span id="globalResult"></span>ms <br /> 
window.mathfloor: <span id="localResult"></span>ms <br /> 
</body> 
</html> 

Mis resultados de la prueba:

[Chromium 5.0.308.0]: 
Math.floor: 49ms 
var mathfloor: 271ms 
window.mathfloor: 40ms 

[IE 8.0.6001.18702] 
Math.floor: 703ms 
var mathfloor: 9890ms [LOL!] 
window.mathfloor: 375ms 

[Firefox [Minefield] 3.7a4pre] 
Math.floor: 42ms 
var mathfloor: 2257ms 
window.mathfloor: 60ms 

[Safari 4.0.4[531.21.10] ] 
Math.floor: 92ms 
var mathfloor: 289ms 
window.mathfloor: 90ms 

[Opera 10.10 build 1893] 
Math.floor: 500ms 
var mathfloor: 843ms 
window.mathfloor: 360ms 

[Konqueror 4.3.90 [KDE 4.3.90 [KDE 4.4 RC1]]] 
Math.floor: 453ms 
var mathfloor: 563ms 
window.mathfloor: 312ms 

La varianza es al azar, por supuesto, pero en su mayor parte

En todos los casos [ esto muestra el tiempo tomado]:
[lleva más tiempo] mathfloor> Math.floor> window.mathfloor [es más rápido]

¿Por qué es esto? En mis proyectos he estado usando var mfloor = Math.floor, y de acuerdo con mis puntos de referencia no tan sorprendentes, mis esfuerzos para "optimizar" en realidad desaceleró la secuencia de comandos por ALOT ...

¿Hay alguna otra forma de hacer que mi código más eficiente"...? Estoy en la etapa en la que básicamente necesito optimizar, así que no, esto no es una "optimización prematura" ...

+0

Quizás esté leyendo esto mal, pero las etiquetas de texto parecen estar refiriéndose a cosas equivocadas. Parece que deben ser: Math.floor: ms
window.mathfloor: ms
var mathfloor: ms
Joe

Respuesta

2

Usted tiene estas dos variables etiquetados incorrectamente:

var mathfloor: <span id="globalResult"></span>ms <br /> 
window.mathfloor: <span id="localResult"></span>ms <br /> 

@ alternativas de David son vale la pena analizar, al igual que algún tipo de memorización.

+0

Me siento estúpido ahora. Gracias. ¿Podría explicar por qué Window.mathfloor tarda una eternidad pero Window.Math.floor no? – Warty

+1

Supongo que es porque los globales son privilegiados en su búsqueda en el objeto ventana; puedes optimizar para ellos Esta página http://www.webreference.com/programming/javascript/jkm3/ confirma sus hallazgos y sugiere que se debe a que el objeto ventana está lleno en el mejor de los casos. – wombleton

0

No estoy seguro de por qué sus puntos de referencia hacen lo que hacen.

Pero si se va a llamar Math.floor menudo puede utilizar esto:

var num = 9.99; 
var floored = ~~num; // 9 
No

que ~~ probablemente se producirá un error en las cuerdas (var num = "9.99"), números fuera de la gama de 32 bits, y los números negativos (~~ redondeará).

Ver this question para obtener un poco más de información.


ACTUALIZACIÓN
Aquí es un modified benchmark

En Chrome que estoy recibiendo el ámbito local volviendo más rápido que Math.floor y el alcance global. (window.mfloor) Tenga en cuenta que no estoy haciendo referencia al mfloor global con la sintaxis window. como en el benchmark original.

Por lo tanto, creo que su prueba tiene 2 problemas (además de la confusión del nombre mencionado en otras respuestas). Una de ellas es que estaba ejecutando el ciclo en window.mfloor y el otro era que tenía una variable local con el mismo nombre que una variable global (esto es solo especulación).

Pruebe el punto de referencia utilizando el enlace jsbin que publiqué y vuelva a contactarme.


aquí está mi punto de referencia para los perezosos:

window.onload = function(){ 

    var k = 0, i=0, n = 2000000, 
    startTime = +(new Date); 
    for(; i < n; ++i) k += Math.floor(9.99); 
    var mathFloorTime = (new Date) - startTime; 

    window.globalMfloor = Math.floor; 
    k = i = 0; 
    startTime = +(new Date); 
    for(; i < n; ++i) k += globalMfloor(9.99); 
    var globalFloorTime = (new Date) - startTime; 

    var mfloor = Math.floor; 
    k = i = 0; 
    startTime = +(new Date); 
    for(; i < n; ++i) k += mfloor(9.99); 
    var localFloorTime = (new Date) - startTime; 

    alert("Math.floor: " + mathFloorTime); 
    alert("globalMfloor: " + globalFloorTime); 
    alert("mfloor: " + localFloorTime); 
};​ 
+0

Mi pregunta estaba destinada a ser más en general. Como en: ¿por qué el acceso a las variables locales toma para siempre =/Math.floor fue solo un ejemplo. Thomas Fuchs presentó la cosa ~~ en una de sus conferencias de optimización, y sí, reduce mucho el tiempo, pero eso no es lo que estoy pidiendo – Warty

+0

bien, solo quería mencionarlo por las dudas. Tengo curiosidad acerca de su pregunta y estoy haciendo algunos puntos de referencia por mi cuenta. Actualizaré mi respuesta si encuentro algo de interés. –

0

Editar: Vaya, no leí la respuesta sobre el nombre del campo mixup. Resulta que, en Firefox, acceder a una variable local era más rápido (tardaba un 80% más) que acceder a Math.floor, pero el acceso a una variable global tomaba un 140% de tiempo.

En mi respuesta original, postulé que las variables locales son más difíciles de acceder que las globales debido al proceso de cierre y otras cosas. Sin embargo, parece ser al revés.

+0

Las variables locales de función se buscan antes que las variables globales. – wombleton

Cuestiones relacionadas