Why is if-else for String faster than switch-case for listing?

Since Java 6 does not have a switch-case for String , I often change the if-else block to case-switch using an enumeration, as in the code below.However, when I tried to test the performance of two alternatives, I found that the switching register would be slower, than the if-else alternative, contrary to what I expected. Here are some of the results I got for the code below

 Iterations If-Else Switch-Case 1 11810 1609181 10 8214 1059115 100 24141 1152494 1000 183975 1580605 10000 4452698 8710648 100000 7069243 19457585 

 package conditionals; import java.util.Random; public class StringConditionalCheck { private static int ifElseCounter = 0; private static int switchCaseCounter = 0; private static final String first = "First"; private static final String second = "Second"; private static final String third = "Third"; private static final String fourth = "Fourth"; enum StringOptions { First, Second, Third, Fourth } public static void main(String[] args) { final int iterations = Integer.parseInt(args[0]); String[] userInputs = generateUserInputs(iterations); // Using if-else long ifelseStartTime = System.nanoTime(); for(int i=0; i<iterations; i++){ useIfElse(userInputs[i]); } long ifelseEndTime = System.nanoTime(); long ifElseDuration = ifelseEndTime - ifelseStartTime; long switchcaseStartTime = System.nanoTime(); for(int i=0; i<iterations; i++){ useSwitchCase(userInputs[i]); } long switchcaseEndTime = System.nanoTime(); //just to verify that both options had the same result. long switchcaseDuration = switchcaseEndTime - switchcaseStartTime; System.out.println(iterations + " " + ifElseDuration + " " + switchcaseDuration + " " + ifElseCounter + " " + switchCaseCounter); } private static String[] generateUserInputs(int numberOfInputs) { String[] generatedInputs = new String[numberOfInputs]; String[] inputsToChooseFrom = new String[]{first, second, third, fourth}; Random r = new Random(); for (int i = 0; i < numberOfInputs; i++) { int choice = r.nextInt(4); generatedInputs[i] = inputsToChooseFrom[choice]; } return generatedInputs; } public static void useSwitchCase(String input) { StringOptions option = StringOptions.valueOf(input); switch(option){ case First: switchCaseCounter += 1; break; case Second: switchCaseCounter += 2; break; case Third: switchCaseCounter += 3; break; case Fourth: switchCaseCounter += 4; break; } } public static void useIfElse(String input) { if(input.equals("First")){ ifElseCounter += 1; }else if(input.equals("Second")){ ifElseCounter += 2; }else if(input.equals("Third")){ ifElseCounter += 3; }else if(input.equals("Fourth")){ ifElseCounter += 4; } } } 

What is the reason for this difference? I expected if-else be slower since there will be more comparisons on average.

+4
source share
2 answers

Because 99% of your time is spent on StringOptions option = StringOptions.valueOf(input); , not switch

+3
source

Based on the source code, calling StringOptions.valueOf performs several complex actions, including building a HashMap for each call, while String.equals simply repeats through the string once.

Compare the source code of Enum.valueOf (which calls Enum.getConstantDirectory) in String.equals .

0
source

Source: https://habr.com/ru/post/1482460/


All Articles