I compared splitting string by regex and by multiple one char splits, using this benchmark
import org.openjdk.jmh.annotations.*; import java.io.IOException; import java.util.concurrent.TimeUnit; public class Test { static String start = "1, 2, 3, 4, 5, 6, 7, 8. 9. 10. 11. 12.1, 2, 3, 4, 5, 6, 7, 8. 9. 10. 11. 12.1, 2, 3, 4, 5, 6, 7, 8. 9. 10. 11. 12.1, 2, 3, 4, 5, 6, 7, 8. 9. 10. 11. 12.1, 2, 3, 4, 5, 6, 7, 8. 9. 10. 11. 12.1, 2, 3, 4, 5, 6, 7, 8. 9. 10. 11. 12.1, 2, 3, 4, 5, 6, 7, 8. 9. 10. 11. 12.1, 2, 3, 4, 5, 6, 7, 8. 9. 10. 11. 12.1, 2, 3, 4, 5, 6, 7, 8. 9. 10. 11. 12.1, 2, 3, 4, 5, 6, 7, 8. 9. 10. 11. 12.1, 2, 3, 4, 5, 6, 7, 8. 9. 10. 11. 12.1, 2, 3, 4, 5, 6, 7, 8. 9. 10. 11. 12.1, 2, 3, 4, 5, 6, 7, 8. 9. 10. 11. 12.1, 2, 3, 4, 5, 6, 7, 8. 9. 10. 11. 12.1, 2, 3, 4, 5, 6, 7, 8. 9. 10. 11. 12."; public static void main(String[] args) throws IOException { org.openjdk.jmh.Main.main(args); } @Fork(value = 1, warmups = 0) @Benchmark @BenchmarkMode(Mode.AverageTime) @Warmup(iterations = 0) @OutputTimeUnit(TimeUnit.NANOSECONDS) public static void splitByRegex() { String test = start; test = String.join("_", test.split("[1,.]")); } @Fork(value = 1, warmups = 0) @Benchmark @BenchmarkMode(Mode.AverageTime) @Warmup(iterations = 0) @OutputTimeUnit(TimeUnit.NANOSECONDS) public static void multipleSplitByOneChar() { String test = start; test = String.join("_", test.split("\.")); test = String.join("_", test.split(",")); test = String.join("_", test.split("1")); } }
and got these results
Benchmark Mode Cnt Score Error Units Test.multipleSplitByOneChar avgt 5 10493,118 ± 572,528 ns/op Test.splitByRegex avgt 5 15519,418 ± 913,220 ns/op
Why splitting by regex is slower than splitting by multiple individual characters, even though they produce the same result?
Note:
- I ran the code on JDK 14.0.2
- I used JMH 1.28
Advertisement
Answer
String.split
implementation has the optimized fast path for splitting by one character.
public String[] split(String regex, int limit) { /* fastpath if the regex is a * (1) one-char String and this character is not one of the * RegEx's meta characters ".$|()[{^?*+\", or * (2) two-char String and the first char is the backslash and * the second is not the ascii digit or ascii letter. */