2012-12-30 10 views
12

Powiel możliwe:
What is the relative performance difference of if/else versus switch statement in Java?Dlaczego pojedynczy "jeśli" wolniejszy niż "przełącznik"?

Biorąc pod uwagę następujące dwa sposoby:

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

badanie pokazuje, że switch wykonuje nieznacznie szybciej (1,4 nanosekundy za połączenia na moim komputerze) niż wersja if.

Zawsze wierzył, że korzyści z przełącznikiem nie kopać, aż przynajmniej kilka ifs można by uniknąć,

Dlaczego switch szybciej niż jednym if?

+4

Czy wiesz, jak wyglądają skompilowane? Może znajdziesz tam odpowiedź. – user1306322

+2

@ user1306322- Trzeba by spojrzeć jeszcze głębiej, aby zbadać, w jaki sposób JVM interpretuje lub kompiluje ten bajt. Pierwszy kod prawdopodobnie użyje instrukcji 'lookupswitch' lub' tableswitch', podczas gdy drugi użyje normalnych skoków. Wszystko zależy od JVM, aby zapewnić ich szybką pracę. – templatetypedef

+3

Czy mógłbyś opublikować swój kod testu porównawczego? –

Odpowiedz

7

Poprzez sprawdzenie kodu bajtowego wynik jest zgodnie z oczekiwaniami:

SWITCH

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 

IF

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

Teraz nie widzę żadnego powodu, dla którego jeden powinna być wolniejsza od drugiej (w każdym razie nie w sensie znaczącym). Jest to z pewnością coś, co jest związane z konkretną implementacją JVM i tym, jak wykonuje te opkody. Zgodnie z powszechną wiedzą instrukcja powinna być wolniejsza, chyba że istnieje wystarczająco dużo przypadków, które sprawiają, że jej konstrukcja jest wartościowa, ale jest to po prostu wspólne myślenie. Każda JVM mogłaby wdrożyć to inaczej, to tylko spekulacja.

Czy na pewno profilujesz wszystko w spójny sposób? (dając czas JVM na rozgrzewkę, utrzymując tylko wyniki w zakresie pewności i wszystkie inne rzeczy, które sprawiają, że profilowanie jest wystarczająco poprawne, aby można było z niego korzystać).

+0

Muszę przyznać, że po uruchomieniu testu wiele razy, * czasami * jeśli jest szybszy niż przełącznik. Twoja uwaga o tym, że nie ma żadnej szczególnej przyczyny różnicy, odzwierciedla to, co znalazłem podczas dalszych testów – Bohemian

Powiązane problemy