After I posted my first video about switch and if statement performance, I received some constructive criticism suggesting I may have oversimplified the problem.
They’re right. I did. I presented a trivial case that was going to perform about the same regardless of the scenario.
I decided to try this experiment again. This time, I generated a massive set of if/else statements and switch statements. There would be 200 conditions to check.
The results? Really cool. As suggested after a certain threshold the compiler uses a hashmap lookup for strings when dealing with switch. What I didn’t expect though was that there is still some string equality checks in the switch version. It’s neat to see though.
What about actual run times? I decided to benchmark and see what was going on. I set up 6 scenarios.
- Switch on a string value
- If-else if using string value
- If, if, if using string value (no else-if)
- Switch on an int
- If-else if on an int
- If, if, if on an int (no else-if)
Here’s the benchmark results.
Input: Garbage
Method | Mean | Error | StdDev |
---|---|---|---|
Test_PrintResponse_String_Switch | 8.596 ns | 0.1456 ns | 0.1291 ns |
Test_PrintResponse_String_If | 861.413 ns | 11.1199 ns | 9.8575 ns |
Test_PrintResponse_String_IfOnly | 863.404 ns | 12.6337 ns | 11.1994 ns |
Test_PrintResponse_Int_Switch | 2.065 ns | 0.0645 ns | 0.0604 ns |
Test_PrintResponse_Int_If | 186.078 ns | 3.7522 ns | 4.4667 ns |
Test_PrintResponse_Int_IfOnly | 176.614 ns | 3.4908 ns | 3.2653 ns |
I picked a value that was outside the domain of matches (either 201 or “201”). In this case, if/if_only performed much worse. The switch used a hashmap and the if version used a lot of branches.
But what if the value is in the domain? I used 198.
Input: Matches
Method | Mean | Error | StdDev |
---|---|---|---|
Test_PrintResponse_String_Switch | 10.975 ns | 0.1283 ns | 0.1138 ns |
Test_PrintResponse_String_If | 1,352.415 ns | 15.9431 ns | 14.9132 ns |
Test_PrintResponse_String_IfOnly | 1,346.991 ns | 26.7235 ns | 24.9972 ns |
Test_PrintResponse_Int_Switch | 2.886 ns | 0.0851 ns | 0.0796 ns |
Test_PrintResponse_Int_If | 171.495 ns | 3.1895 ns | 2.9834 ns |
Test_PrintResponse_Int_IfOnly | 178.288 ns | 3.4112 ns | 3.1908 ns |
The performance is worse? I’ll chalk this up to two things – measurement error and the possibility that I picked a bad example. I’m sure there are other inputs that would perform better.
I’m not claiming this is the definitive answer on if or switch being faster! I’m just saying in this particular case for this particular code, switch was faster.
Plus studying the IL is a ton of fun. Just saying!