简体   繁体   中英

Is it faster to use a switch statement vs an if statement, or put the cases inside a hashMap and just use the contains method?

I currently have this very long if statement:

if (somesTring != null && !"".equals(somestring)
  SomeClass.doSomething();
else if (somesTring != null && !"".equals(somestring)
  SomeClass.doAnother();
...
else
  SomeClass.giveUp();

I think this would execute poorly when the item in question is at the bottom of the decision tree. I'm considering the switch statement, which, according to my coworker, is faster. The sad thing is that the comparisons are performed with strings, which is not supported by the switch statement. Maybe I can get the hashcodes of the strings involved and use that for the switch statement.

I'm also considering a hashmap that contains each of those strings and make decisions with the help of the containsKey method. This, however, involves having to slice up a class that contains a lot of static methods and make each of those methods as a somewhat executable object. By doing this, I can dispose of the very large "if" statement.

Which of the said approaches make more sense with regards to execution time, good practice, and maintainability? Other suggestions are welcome :)

Use the command pattern. You can get rid of the if statements completely

Here is similar question

Long list of if statements in Java

By using command,

execution time - You can verify. Don't think its going to be a big difference.

good practice - Yes

maintainability - Yes, there is a pattern established.

"Use switch instead of if-else, its more readable and has better performance." I have to admit that this was one of my favorite code review comment. Until one fine day, while hacking Apache Sanselan's image format decoding function, I tried optimizing the code based on the same comments and while benchmark there was hardly any difference. I thought about investigating it further. Though found some interesting mail chains, though about posting my finding.

To begin with decided to run some samples on switch and if-else constructs and analyze further.

Wrote three function 1. For if-else - a if-else ladder based on int comparisons 2. For Switch - switch with 21 cases, from 1 to 20 3. For Switch - switch with sparse random values

The reason for choosing two functions for switch was this statement from VM spec "Compilation of switch statements uses the tableswitch and lookupswitch instructions"

Lets see the function codes

if-else view sourceprint

public static void testIfElse(int jumpLabel) { 

    if(1 == jumpLabel) { 
        System.out.println("1"); 
    } else if(2 == jumpLabel) { 
        System.out.println("2"); 
    } else if(3 == jumpLabel) { 
        System.out.println("3"); 
    } else if(4 == jumpLabel) { 
        System.out.println("4"); 
    } 
    // Removed for simplicity 
    else { 
        System.out.println("default"); 
    } 
}

Lets see the switch functions

Finite switch version view sourceprint?

public static void testSwitchFinite(int jumpLable) { 

    switch (jumpLable) { 
        case 1:        
            System.out.println("1");  
            break; 

         case 2:    
            System.out.println("2"); 
            break; 

         case 3:    
            System.out.println("3");     
            break; 

         case 4:    
            System.out.println("4");      
            break;  

         case 5: 
            System.out.println("5");       
            break;  

         // Removed other cases for simplicity 
         default: 
            System.out.println("default");     
         break; 
    } 
}

Sparse switch version view sourceprint?

public static void testSwitchSparse(int jumpLable) { 

    switch (jumpLable) { 
        case 100: 
            System.out.println("1"); 
            break; 

        case -1: 
            System.out.println("2"); 
            break; 

        case 5000: 
            System.out.println("3"); 
            break; 

        case -8: 
            System.out.println("4"); 
            break; 

        case 1600: 
            System.out.println("5"); 
            break; 

        case 250: 
            System.out.println("250"); 
            break; 

        // Removed other cases for simplicity 
        default: 
            System.out.println("default"); 
            break; 
    } 
}

With the groundwork done, its the benchmarking time. The benchmarking strategy was simple. Run these functions in loop and see the result, with iteration ranging from 100 to 1000.

Lets look at one of the functions

view sourceprint?

 public static void testSwitchPerf(int iteration) { 

    long t1 = System.nanoTime(); 
    for (int i = 0; i < iteration; i++) { 
        testSwitchFinite(i); 
    } 

    long t2 = System.nanoTime(); 

    System.out.println("Time Taken (switch) = "+(t2 - t1)/1000000); 

}

Well this was the ground work, after executing the conditions, here is the data

Iteration -> 100 1000 
if-else 8 ms 69 ms 
switch finite 3 ms 34 ms 
switch sparse 7 ms 21 ms 

NOTE: There is some difference due to the way data is provided and the sample space doesn't provide precise results. However, since the sample space is same for both, it would serve its purpose

Conclusion 1. There is no significant execution difference between if-else and switch. The difference observed is due to the sample space choosen. 2. If using if-else, its always recommended to put frequently used if condition at the top of if-else ladder 3. The finite switch statement was converted to tableswitch and sparse switch was converted to lookupswitch

would be interested to hear from folks about their experience in relation to this. I would say, i still prefer switch for readability. Henceforth, my review comment shall be modified as "Use switch instead of if-else, its more readable and has better performance

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM