2010-04-20 21 views
6

Stavo cercando di confrontare il guadagno/perdita di "caching" matematico, nella speranza che potessi effettuare chiamate più velocemente.Le variabili locali richiedono 7 volte più tempo di accesso rispetto alle variabili globali?

Qui è stato il test:

<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> 

I miei risultati del test:

[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 è casuale, naturalmente, ma per la maggior parte

In tutti i casi [ questo mostra il tempo impiegato]:
[richiede più tempo] mathfloor> Math.floor> window.mathfloor [è più veloce]

Perché è questo? Nei miei progetti ho utilizzato var mfloor = Math.floor e, secondo i miei benchmark non così straordinari, i miei sforzi per "ottimizzare" in realtà rallentavano lo script di ALOT ...

C'è qualche altro modo per rendere il mio codice più efficiente"...? Sono al punto in cui ho fondamentalmente bisogno di ottimizzare, quindi no, questa non è "ottimizzazione prematura" ...

+0

Potrei leggere male, ma le etichette di testo sembrano riferirsi alle cose sbagliate. Sembra come dovrebbero essere: Math.floor: ms
window.mathfloor: ms
var mathfloor: ms
Joe

risposta

2

Avete queste due variabili etichettati in modo errato:

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

@ alternative di David sono merita di essere esaminata, come farebbe una sorta di memoizzazione.

+0

Mi sento stupido ora. Grazie. Potresti spiegare perché Window.mathfloor richiede per sempre, ma Window.Math.floor no? – Warty

+1

Suppongo che sia perché le globali sono privilegiate nella loro ricerca sull'oggetto della finestra; puoi ottimizzare per loro. Questa pagina http://www.webreference.com/programming/javascript/jkm3/ conferma i risultati e suggerisce che l'oggetto finestra è affollato nel migliore dei casi. – wombleton

0

Non sono sicuro del motivo per cui i benchmark fanno quello che fanno.

Ma se avete intenzione di chiamare Math.floor spesso è possibile utilizzare questo:

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

che ~~ probabilmente fallire su stringhe (var num = "9.99"), i numeri di fuori del campo a 32 bit, e numeri negativi (~~ verrà arrotondato).

Vedere this question per ulteriori informazioni.


UPDATE
Ecco un modified benchmark

Su Chrome sto ottenendo l'ambito locale, il ritorno più veloce rispetto Math.floor e la portata globale. (window.mfloor) Si noti che non sto riferendo il mfloor globale con la sintassi window. come nel benchmark originale.

Quindi, penso che il test abbia 2 problemi (oltre al nome variabile mix up menzionato in altre risposte). Uno è che stavi eseguendo il ciclo su window.mfloor e l'altro è che avevi una variabile locale con lo stesso nome di una variabile globale (questa è solo una speculazione).

Prova il benchmark usando il link jsbin che ho postato e torna da me.


ecco il mio punto di riferimento per i più pigri:

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

La mia domanda era mirata ad essere più generale. Come in: perché l'accesso alle variabili locali dura per sempre =/Math.floor era solo un esempio. Thomas Fuchs ha presentato la cosa in una delle sue conferenze sull'ottimizzazione, e sì, riduce il tempo molto, ma non è quello che sto chiedendo per – Warty

+0

ok, volevo solo dirlo per ogni evenienza. Sono curioso della tua domanda e sto facendo alcuni benchmark per conto mio. Aggiornerò la mia risposta se trovo qualcosa di interessante. –

0

Modifica: Oops, non ho letto la risposta sul nome del campo mixup. Si scopre che, in Firefox, l'accesso a una variabile locale è stato più veloce (ha richiesto l'80% di tempo) di accedere a Math.floor, ma l'accesso a una variabile globale è durato il 140%.

Nella mia risposta originale, ho postulato che le variabili locali sono più difficili da accedere rispetto a quelle globali a causa dell'elaborazione della chiusura e quant'altro. Tuttavia, sembra essere il contrario.

+0

Le variabili locali della funzione vengono ricercate prima delle variabili globali. – wombleton