2013-08-20 12 views
7

Ho visto un post su http://www.jquery4u.com/javascript/shorthand-javascript-techniques/ in cui parla di un modo alternativo di utilizzare le istruzioni switch.JSON come sintassi vs istruzione switch javascript

Ho creato uno snippet di seguito, ma non sono sicuro del motivo per cui l'alternato è lento al 99%.

function doX(){} 
function doY(){} 
function doN(){} 
var something = 1; 

var cases = { 
    1: doX, 
    2: doY, 
    3: doN 
}; 
if (cases[something]) { 
    cases[something](); 
} 

http://jsperf.com/alternateswitch

Qualche idea?

+0

Proprio come la versione abbreviata di se/o di cui sta parlando, è più breve, ma non è affatto più veloce. –

+2

Questa sintassi "JSON" è solo un oggetto. – Blender

+6

Penso anche che gran parte della differenza nei risultati sia un uso improprio di jsperf. Assicurati di aggiungere un qualsiasi codice temporale alla parte di configurazione dei test. Ecco un esempio che utilizza il tuo codice: http: // jsperf.com/alternateswitch/3 –

risposta

3

L'autore non ha mai affermato che il codice più breve, che è solo una mappa hash dei possibili casi, sarebbe effettivamente più veloce. Ovviamente, la creazione dell'array ha un impatto negativo sulle prestazioni quando la si esegue in una suite di test. Allo stesso tempo, l'istruzione switch è un codice compilato.

Vedrete qualche miglioramento se il vostro codice viene riutilizzato, vale a dire si mantiene il valore di cases; Ho misurato una differenza di circa il 20-30% in this test case, a seconda di quale caso si verifica più spesso.

Detto questo, un test delle prestazioni isolato come questo non sarà utile a meno che il codice non venga eseguito all'interno di un circuito chiuso, perché i casi di test funzionano a 50 milioni di operazioni al secondo sul mio computer di casa. Le differenze tra i due devono quindi essere basate su altri fattori, come la chiarezza del codice o il fatto che le dichiarazioni switch sono facili da incasinare se si dimentica di inserire una dichiarazione break;.

+0

Il test case è ingiusto. Stai facendo due volte l'array associativo. – invisal

+0

@invisal È il codice originale e senza la ricerca extra il codice in modo rigoroso non è lo stesso di un 'switch'. –

7

La sintassi "JSON" è solo un oggetto. Inoltre, il tuo confronto è un po 'ingiusto qui, mentre crei un oggetto nuovo di zecca ogni singolo ciclo temporizzato, che è piuttosto costoso.

Se si sposta la creazione di oggetti alla sezione di configurazione, la differenza di velocità diventa neglibile: http://jsperf.com/alternateswitch/4

Se si rimuove la dichiarazione if, l'oggetto sarà un po 'più veloce (almeno per me): http://jsperf.com/alternateswitch/5. La ricerca di proprietà extra e il controllo della verità rallentano.

3
  • Credo che l'oggetto Javascript sia un array associativo che di solito viene implementato come tabella hash. Ogni ricerca richiede una chiave per andare attraverso una funzione di hashing. La funzione di hash è come una doppia lama. Per dati di piccole dimensioni, sarebbe più lento di un if-else-else. Tuttavia, per i dati più grandi, supererà l'ordinario if-elseif-else
  • È molto ingiusto che tu stia favorendo lo switch, fai in modo che la variabile che stai cercando sia al primo caso. Pertanto, la complessità di switch è O (1) per il test.
+1

Huh, non avrei mai immaginato che l'ordine dei casi nell'istruzione switch abbia effettivamente un impatto significativo sulle prestazioni: http://jsperf.com/alternateswitch/8 – Blender

+0

La complessità del codice per uno switch è sempre O (1) btw :) –

+0

@Jack, se hai N casi, la complessità dell'interruttore non è sempre O (1). Credo che 'switch' in Javascript sia implementato in modo simile a if-else, non come un jump-table. – invisal

1

Generalmente le istruzioni switch sono ottimizzate dal compilatore/interprete. Sono persino più veloci delle dichiarazioni concatenate if-else. Utilizzando un oggetto JSON anziché l'istruzione switch, si ignora l'ottimizzazione del motore Javascript.

Problemi correlati