12

Possible Duplicate:
What is the relative performance difference of if/else versus switch statement in Java?

Given the following two methods:

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

testing shows that the switch executes marginally faster (1.4 nanoseconds per call on my machine) than the if version.

I had always believed that the benefit of a switch didn't kick in until at least a few ifs could be avoided,

Why is switch faster than a single if?

Community
  • 1
  • 1
Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • 4
    Do you know how they look compiled? Maybe you can find your answer there. – user1306322 Dec 30 '12 at 19:46
  • 2
    @user1306322- You'd have to look even deeper to investigate how the JVM was interpreting or compiling that bytecode. The first code will probably use a `lookupswitch` or `tableswitch` instruction, while the second will use normal jumps. It's all up to the JVM to make them work fast. – templatetypedef Dec 30 '12 at 19:47
  • 3
    Could you post your benchmarking code? – Patricia Shanahan Dec 30 '12 at 19:48
  • @PatriciaShanahan testing code compares `nanoTime()` for `for (int i = 0; i < 999999; i++) x += useIf(i)` (`x` is asserted) – Bohemian Dec 30 '12 at 19:50
  • have a look at this http://stackoverflow.com/a/2086550/1180720 – gefei Dec 30 '12 at 19:53
  • @Bohemian Did you control for issues such as, for example, which test is done first? There are a lot of details that can affect the results of Java micro-benchmarking. – Patricia Shanahan Dec 30 '12 at 19:57
  • @PatriciaShanahan Actually, further testing showed that sometimes the if was faster. My conclusion is that the difference is small for small numbers of `ifs`. Perhaps for larger numbers of `ifs`, changing to switch may be warranted for performance-sensitive code. But we are talking about nanoseconds. – Bohemian Dec 30 '12 at 20:01

2 Answers2

7

By checking the bytecode the result is as expected:

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

Now I don't see any particular reason for which one should be slower than the other (not by a significative amount in any case). This is surely something that is related to the specific JVM implementation and how it executes these opcodes. According to common knowledge the TABLESWITCH instruction should be slower unless there are enough cases that makes its construction valuable but this is just common thinking. Every JVM could implement it differently so this is just speculation.

Are you sure to profiled everything in a consistent way? (by giving time to JVM to warm up, by keeping just results within a confidence range and all the other things that make profiling enough correct to be used)

Jack
  • 131,802
  • 30
  • 241
  • 343
  • I must confess that after running the test many times, *sometimes* the if is faster than the switch. Your comment about there not being any particular reason for a difference reflects what I found with further testing – Bohemian Dec 30 '12 at 19:59
0

This type of comparison is analyzed in If-else vs switch – Which is better?. However, try to compile to native code using gcj and compare obtained results with result from the use of bytecode.

Mihai8
  • 3,113
  • 1
  • 21
  • 31