2010-05-27 15 views
95

Ragazzi ho un paio di domande:interruttore Javascript contro if ... else if ... else

  1. C'è una differenza di prestazioni in JavaScript tra una dichiarazione e di un switchif...else?
  2. Se sì, perché?
  3. Il comportamento di switch e if...else è diverso nei vari browser? (Firefox, IE, Chrome, Opera, Safari)

La ragione di questa domanda è sembra che ricevo una migliore performance su una dichiarazione switch con 1000s circa i casi in Firefox.


cura Unfortuantly questo non è il mio codice Javascript è prodotto serverside da una libreria compilata e non ho accesso al codice. Il metodo che produce il javascript è chiamato

CreateConditionals(string name, string arrayofvalues, string arrayofActions) 

nota arrayofvalues è un elenco separato.

ciò che produce è

function [name] (value) { 
    if (value == [value from array index x]) { 
    [action from array index x] 
    } 
} 

Nota: dove [name] = il nome passato alla funzione serverside

Ora ho cambiato l'uscita della funzione da inserire in una TextArea, ha scritto un codice JavaScript per analizzare la funzione e convertirla in un set di istruzioni case.

finalmente eseguo la funzione e funziona bene ma le prestazioni differiscono in IE e Firefox.

+1

Vorrei suggerire un esempio di codice per esaminare cosa è ottimale. Voglio dire, ci dev'essere una ragione per cui lo stai chiedendo, vero? – jcolebrand

+0

Si prega di postare ciò che si sta facendo, perché ci sono pochissimi casi nella mia lunga esperienza per i quali direi che un'istruzione switch di 100 casi o una serie di 100 se/else è stata una buona idea. – Pointy

+0

scusate ragazzi non 100 ma migliaia di condizioni –

risposta

74

Rispondere in termini generali:

  1. Sì, al solito LY.
  2. See More Info Here
  3. Sì, perché ciascuno ha un diverso motore di elaborazione JS, tuttavia, in esecuzione di un test sul sito di seguito, l'interruttore sempre fuori eseguito il caso, elseif su un gran numero di iterazioni.

Test site

+0

Grazie a Tommy, il tuo sito di esempio è stato piacevole da usare quando si cercava di determinare quale fosse la differenza di prestazioni tra if e switch. È così minimale che mi ha portato alla conclusione che il mio problema era altrove, come ho notato nel mio commento con la mia domanda. Grazie per il tuo tempo. –

+1

+1 per l'articolo molto interessante – Martin

+1

Se si desidera un TLDR di quando utilizzare quali condizionali qui è un collegamento diretto a un segmento nell'articolo che si rivolge a: http://oreilly.com/server-administration/excerpts/even-faster -websites/writing-efficient-javascript.html # the_fastest_conditionals – edhedges

3

C'è una differenza preformance in JavaScript tra un'istruzione switch e un se ... else if .... altro?

Io non la penso così, switch è utile/breve se si vuole evitare che più if-else condizioni.

è il comportamento di switch e if ... else if ... else diverso attraverso browser? (Firefox, IE, Chrome, Opera, Safari )

comportamento è lo stesso in tutti i browser :)

+2

'switch è utile/breve se vuoi prevenire più condizioni if-else. Sì, signore, ottimo post. –

6
  1. Se c'è una differenza, non sarà mai grande abbastanza per essere notato.
  2. N/A
  3. No, funzionano tutti in modo identico.

In pratica, utilizzare qualsiasi cosa rende il codice più leggibile. Ci sono sicuramente luoghi in cui uno o l'altro costrutto rende più pulito, più leggibile e più manutenibile.Questo è molto più importante che forse si risparmia qualche nanosecondo nel codice JavaScript.

+4

In javascript, in particolare, la semantica e la leggibilità (e quindi la manutenibilità) annullano qualsiasi differenza prestazionale localizzata tra 'if..else' e' switch' causata da una versione unica del browser hardware e del sistema operativo. – jball

+1

Non so se sono d'accordo, potrebbe effettivamente essere notato se è usato in un ciclo con dire, un grande database, attraversando un albero ecc. – ghoppe

+1

non sono assolutamente d'accordo. man mano che le applicazioni web diventano sempre più complesse, questa differenza potrebbe essere significativa per l'applicazione e potrebbe cambiare in base ai browser. – joshvermaire

1
  1. Workbenching potrebbe comportare alcune differenze molto piccole, in alcuni casi, ma la via della trasformazione è il browser dipende in ogni caso quindi non vale la pena
  2. A causa di diversi modi di elaborazione
  3. Non si può chiamare un browser, se il comportamento sarebbe stato diverso in ogni caso
6

parte della sintassi, un interruttore può essere implementato utilizzando un albero che rende O(log n), mentre un if/else deve essere attuata con un approccio procedurale O(n). Più spesso sono entrambi processati proceduralmente e l'unica differenza è la sintassi, e inoltre conta davvero - a meno che non stiate scrivendo staticamente 10k casi di if/else comunque?

+0

7 anni dopo ... Non vedo come sia possibile l'implementazione dell'albero, tranne nel caso di valori numerici costanti del caso). –

49

A volte è meglio non usare nessuno dei due. Per esempio, in una situazione di "spedizione", Javascript permette di fare le cose in un modo completamente diverso:

function dispatch(funCode) { 
    var map = { 
    'explode': function() { 
     prepExplosive(); 
     if (flammable()) issueWarning(); 
     doExplode(); 
    }, 

    'hibernate': function() { 
     if (status() == 'sleeping') return; 
     // ... I can't keep making this stuff up 
    }, 
    // ... 
    }; 

    var thisFun = map[funCode]; 
    if (thisFun) thisFun(); 
} 

Impostazione multi-way ramificazione con la creazione di un oggetto ha un sacco di vantaggi. È possibile aggiungere e rimuovere funzionalità in modo dinamico. È possibile creare la tabella di spedizione dai dati. Puoi esaminarlo a livello di programmazione. Puoi costruire i gestori con altre funzioni.

C'è l'overhead aggiunto di una chiamata di funzione per ottenere l'equivalente di un "caso", ma il vantaggio (quando ci sono molti casi) di una ricerca hash per trovare la funzione per una chiave particolare.

13

La differenza di prestazioni tra un switch e if...else if...else è piccola, in pratica fanno lo stesso lavoro. Una differenza tra loro che può fare la differenza è che l'espressione da testare viene valutata solo una volta in un switch mentre viene valutata per ogni if. Se è costoso valutare l'espressione, farlo una volta è ovviamente più veloce di farlo cento volte.

La differenza nell'implementazione di quei comandi (e di tutti gli script in generale) differisce molto tra i browser. È comune vedere differenze di prestazioni piuttosto grandi per lo stesso codice in diversi browser.

Poiché è difficile testare tutto il codice in tutti i browser, è necessario scegliere il codice più adatto a quello che si sta facendo e cercare di ridurre la quantità di lavoro svolto piuttosto che ottimizzare il modo in cui viene eseguito.

0

Pointy's answer suggerisce l'uso di un oggetto letterale come alternativa alla switch o if/else. Mi piace questo approccio troppo, ma il codice nella risposta crea un nuovo oggetto map ogni volta che la funzione viene chiamata dispatch:

function dispatch(funCode) { 
    var map = { 
    'explode': function() { 
     prepExplosive(); 
     if (flammable()) issueWarning(); 
     doExplode(); 
    }, 

    'hibernate': function() { 
     if (status() == 'sleeping') return; 
     // ... I can't keep making this stuff up 
    }, 
    // ... 
    }; 

    var thisFun = map[funCode]; 
    if (thisFun) thisFun(); 
} 

Se map contiene un gran numero di voci, questo può creare un overhead significativo. È meglio impostare la mappa azioni una sola volta e quindi utilizzare la mappa già creata ogni volta, ad esempio:

var actions = { 
    'explode': function() { 
     prepExplosive(); 
     if(flammable()) issueWarning(); 
     doExplode(); 
    }, 

    'hibernate': function() { 
     if(status() == 'sleeping') return; 
     // ... I can't keep making this stuff up 
    }, 
    // ... 
}; 

function dispatch(name) { 
    var action = actions[name]; 
    if(action) action(); 
}