2012-12-30 2 views
12

Eventuali duplicati:
What is the relative performance difference of if/else versus switch statement in Java?Perché un singolo "se" è più lento di "switch"?

Dati i seguenti due metodi:

public static int useSwitch(int i) { 
    switch (i) { 
    case 0: 
     return 1; 
    default: 
     return 0; 
    } 
} 

public static int useIf(int i) { 
    if (i == 0) 
     return 1; 
    return 0; 
} 

test mostra che il switch esegue marginalmente più veloce (1,4 nanosecondi per chiamata sulla mia macchina) rispetto alla versione if.

Avevo sempre creduto che il beneficio di uno switch non ha calci fino a quando almeno un paio ifs potrebbero essere evitati,

Perché switch più veloce di un singolo if?

+4

Sai come appaiono compilati? Forse puoi trovare la tua risposta lì. – user1306322

+2

@ user1306322- Dovresti cercare in modo ancora più approfondito per indagare su come la JVM stia interpretando o compilando quel bytecode. Il primo codice utilizzerà probabilmente l'istruzione 'lookupswitch' o' tableswitch', mentre il secondo userà i normali salti. Dipende tutto dalla JVM per farli funzionare velocemente. – templatetypedef

+3

Potresti pubblicare il tuo codice di benchmarking? –

risposta

7

Controllando il bytecode il risultato è come previsto:

INTERRUTTORE

public static useSwitch(I)I 
L0 
    ILOAD 0 
    TABLESWITCH 
    0: L1 
    default: L2 
L1 
    INVOKESTATIC Tests.a()I 
    IRETURN 
L2 
    INVOKESTATIC Tests.b()I 
    IRETURN 

SE

public static useIf(I)I 
L0 
    ILOAD 0 
    IFNE L1 
L2 
    INVOKESTATIC Tests.a()I 
    IRETURN 
L1 
    INVOKESTATIC Tests.b()I 
    IRETURN 

Ora non vedo alcuna ragione particolare per la quale si dovrebbe essere più lento dell'altro (non con una quantità significativa in ogni caso). Questo è sicuramente qualcosa che è correlato all'implementazione JVM specifica e al modo in cui esegue questi opcode. Secondo la conoscenza comune l'istruzione TABLESWITCH dovrebbe essere più lenta a meno che non ci siano casi sufficienti che rendono la sua costruzione valida, ma questo è solo il pensiero comune . Ogni JVM potrebbe implementarlo in modo diverso, quindi questa è solo una speculazione.

Sei sicuro di profilare tutto in modo coerente? (dando tempo a JVM di riscaldarsi, mantenendo solo i risultati entro un intervallo di fiducia e tutte le altre cose che rendono il profiling sufficientemente corretto da utilizzare)

+0

Devo confessare che dopo aver eseguito il test molte volte, * a volte * il se è più veloce dello switch. Il tuo commento sul fatto che non ci sia alcun motivo particolare per una differenza riflette ciò che ho trovato con ulteriori test – Bohemian