Here's a performance test with several alternatives (some are case sensitive and others case insensitive):
public static void main(String[] args) { // Why 4 * 4: // The test contains 3 values (val1, val2 and val3). Checking 4 combinations will check the match on all values, and the non match; // Try 4 times: lowercase, UPPERCASE, prefix + lowercase, prefix + UPPERCASE; final int NUMBER_OF_TESTS = 4 * 4; final int EXCUTIONS_BY_TEST = 1_000_000; int numberOfMatches; int numberOfExpectedCaseSensitiveMatches; int numberOfExpectedCaseInsensitiveMatches; // Start at -1, because the first execution is always slower, and should be ignored! for (int i = -1; i < NUMBER_OF_TESTS; i++) { int iInsensitive = i % 4; List<String> testType = new ArrayList<>(); List<Long> timeSteps = new ArrayList<>(); String name = (i / 4 > 1 ? "dummyPrefix" : "") + ((i / 4) % 2 == 0 ? "val" : "VAL" )+iInsensitive ; numberOfExpectedCaseSensitiveMatches = 1 <= i && i <= 3 ? EXCUTIONS_BY_TEST : 0; numberOfExpectedCaseInsensitiveMatches = 1 <= iInsensitive && iInsensitive <= 3 && i / 4 <= 1 ? EXCUTIONS_BY_TEST : 0; timeSteps.add(System.currentTimeMillis()); //----------------------------------------- numberOfMatches = 0; testType.add("List (Case sensitive)"); for (int j = 0; j < EXCUTIONS_BY_TEST; j++) { if (Arrays.asList("val1", "val2", "val3").contains(name)) { numberOfMatches++; } } if (numberOfMatches != numberOfExpectedCaseSensitiveMatches) { throw new RuntimeException(); } timeSteps.add(System.currentTimeMillis()); //----------------------------------------- numberOfMatches = 0; testType.add("Set (Case sensitive)"); for (int j = 0; j < EXCUTIONS_BY_TEST; j++) { if (new HashSet<>(Arrays.asList(new String[] {"val1", "val2", "val3"})).contains(name)) { numberOfMatches++; } } if (numberOfMatches != numberOfExpectedCaseSensitiveMatches) { throw new RuntimeException(); } timeSteps.add(System.currentTimeMillis()); //----------------------------------------- numberOfMatches = 0; testType.add("OR (Case sensitive)"); for (int j = 0; j < EXCUTIONS_BY_TEST; j++) { if ("val1".equals(name) || "val2".equals(name) || "val3".equals(name)) { numberOfMatches++; } } if (numberOfMatches != numberOfExpectedCaseSensitiveMatches) { throw new RuntimeException(); } timeSteps.add(System.currentTimeMillis()); //----------------------------------------- numberOfMatches = 0; testType.add("OR (Case insensitive)"); for (int j = 0; j < EXCUTIONS_BY_TEST; j++) { if ("val1".equalsIgnoreCase(name) || "val2".equalsIgnoreCase(name) || "val3".equalsIgnoreCase(name)) { numberOfMatches++; } } if (numberOfMatches != numberOfExpectedCaseInsensitiveMatches) { throw new RuntimeException(); } timeSteps.add(System.currentTimeMillis()); //----------------------------------------- numberOfMatches = 0; testType.add("ArraysBinarySearch(Case sensitive)"); for (int j = 0; j < EXCUTIONS_BY_TEST; j++) { if (Arrays.binarySearch(new String[]{"val1", "val2", "val3"}, name) >= 0) { numberOfMatches++; } } if (numberOfMatches != numberOfExpectedCaseSensitiveMatches) { throw new RuntimeException(); } timeSteps.add(System.currentTimeMillis()); //----------------------------------------- numberOfMatches = 0; testType.add("Java8 Stream (Case sensitive)"); for (int j = 0; j < EXCUTIONS_BY_TEST; j++) { if (Stream.of("val1", "val2", "val3").anyMatch(name::equals)) { numberOfMatches++; } } if (numberOfMatches != numberOfExpectedCaseSensitiveMatches) { throw new RuntimeException(); } timeSteps.add(System.currentTimeMillis()); //----------------------------------------- numberOfMatches = 0; testType.add("Java8 Stream (Case insensitive)"); for (int j = 0; j < EXCUTIONS_BY_TEST; j++) { if (Stream.of("val1", "val2", "val3").anyMatch(name::equalsIgnoreCase)) { numberOfMatches++; } } if (numberOfMatches != numberOfExpectedCaseInsensitiveMatches) { throw new RuntimeException(); } timeSteps.add(System.currentTimeMillis()); //----------------------------------------- numberOfMatches = 0; testType.add("RegEx (Case sensitive)"); // WARNING: if values contains special characters, that should be escaped by Pattern.quote(String) for (int j = 0; j < EXCUTIONS_BY_TEST; j++) { if (name.matches("val1|val2|val3")) { numberOfMatches++; } } if (numberOfMatches != numberOfExpectedCaseSensitiveMatches) { throw new RuntimeException(); } timeSteps.add(System.currentTimeMillis()); //----------------------------------------- numberOfMatches = 0; testType.add("RegEx (Case insensitive)"); // WARNING: if values contains special characters, that should be escaped by Pattern.quote(String) for (int j = 0; j < EXCUTIONS_BY_TEST; j++) { if (name.matches("(?i)val1|val2|val3")) { numberOfMatches++; } } if (numberOfMatches != numberOfExpectedCaseInsensitiveMatches) { throw new RuntimeException(); } timeSteps.add(System.currentTimeMillis()); //----------------------------------------- numberOfMatches = 0; testType.add("StringIndexOf (Case sensitive)"); // WARNING: the string to be matched should not contains the SEPARATOR! final String SEPARATOR = ","; for (int j = 0; j < EXCUTIONS_BY_TEST; j++) { // Don't forget the SEPARATOR at the begin and at the end! if ((SEPARATOR+"val1"+SEPARATOR+"val2"+SEPARATOR+"val3"+SEPARATOR).indexOf(SEPARATOR + name + SEPARATOR)>=0) { numberOfMatches++; } } if (numberOfMatches != numberOfExpectedCaseSensitiveMatches) { throw new RuntimeException(); } timeSteps.add(System.currentTimeMillis()); //----------------------------------------- StringBuffer sb = new StringBuffer("Test ").append(i) .append("{ name : ").append(name) .append(", numberOfExpectedCaseSensitiveMatches : ").append(numberOfExpectedCaseSensitiveMatches) .append(", numberOfExpectedCaseInsensitiveMatches : ").append(numberOfExpectedCaseInsensitiveMatches) .append(" }:\n"); for (int j = 0; j < testType.size(); j++) { sb.append(String.format(" %4d ms with %s\n", timeSteps.get(j + 1)-timeSteps.get(j), testType.get(j))); } System.out.println(sb.toString()); } }
Conclusion (only in the worst case, when you need to check all the elements without matching with any):
Test 4{ name : VAL0, numberOfExpectedCaseSensitiveMatches : 0, numberOfExpectedCaseInsensitiveMatches : 0 }: 43 ms with List (Case sensitive) 378 ms with Set (Case sensitive) 22 ms with OR (Case sensitive) 254 ms with OR (Case insensitive) 35 ms with ArraysBinarySearch(Case sensitive) 266 ms with Java8 Stream (Case sensitive) 531 ms with Java8 Stream (Case insensitive) 1009 ms with RegEx (Case sensitive) 1201 ms with RegEx (Case insensitive) 107 ms with StringIndexOf (Case sensitive)
Manuel Romeiro Jun 21 '19 at 15:28 2019-06-21 15:28
source share