When I compared performance of Apache's StringUtils.replace()
vs String.replace()
I was surprised to know that the former is about 4 times faster. I used Google's Caliper framework to measure performance. Here's my test
public class Performance extends SimpleBenchmark { String s = "111222111222"; public int timeM1(int n) { int res = 0; for (int x = 0; x < n; x++) { res += s.replace("111", "333").length(); } return res; } public int timeM2(int n) { int res = 0; for (int x = 0; x < n; x++) { res += StringUtils.replace(s, "111", "333", -1).length(); } return res; } public static void main(String... args) { Runner.main(Performance.class, args); } }
output
0% Scenario{vm=java, trial=0, benchmark=M1} 9820,93 ns; ?=1053,91 ns @ 10 trials 50% Scenario{vm=java, trial=0, benchmark=M2} 2594,67 ns; ?=58,12 ns @ 10 trials benchmark us linear runtime M1 9,82 ============================== M2 2,59 =======
Why is that? Both methods seem to do the same work, StringUtils.replace()
is even more flexible.
replaceAll is considerably slower than doing the job yourself. Bookmark this question.
replaceAll() The replaceAll() method returns a new string with all matches of a pattern replaced by a replacement . The pattern can be a string or a RegExp , and the replacement can be a string or a function to be called for each match. The original string is left unchanged.
The difference between replace() and replaceAll() method is that the replace() method replaces all the occurrences of old char with new char while replaceAll() method replaces all the occurrences of old string with the new string.
Java String replace() MethodThe replace() method searches a string for a specified character, and returns a new string where the specified character(s) are replaced.
In modern Java, this is not the case anymore. String.replace
was improved in Java-9 moving from regular expression to StringBuilder, and was improved even more in Java-13 moving to direct allocation of the target byte[]
array calculating its exact size in advance. Thanks to internal JDK features used, like the ability to allocate an uninitialized array, ability to access String coder and ability to use private String
constructor which avoids copying, it's unlikely that current implementation can be beaten by a third-party implementation.
Here are my benchmarking results for your test using JDK 8, JDK 9 and JDK 13 (caliper:0.5-rc1; commons-lang3:3.9)
Java 8 (4x slower indeed):
0% Scenario{vm=java, trial=0, benchmark=M1} 291.42 ns; σ=6.56 ns @ 10 trials 50% Scenario{vm=java, trial=0, benchmark=M2} 70.34 ns; σ=0.15 ns @ 3 trials benchmark ns linear runtime M1 291.4 ============================== M2 70.3 =======
Java 9 (almost equal performance):
0% Scenario{vm=java, trial=0, benchmark=M2} 99,15 ns; σ=8,34 ns @ 10 trials 50% Scenario{vm=java, trial=0, benchmark=M1} 103,43 ns; σ=9,01 ns @ 10 trials benchmark ns linear runtime M2 99,1 ============================ M1 103,4 ==============================
Java 13 (standard method is 38% faster):
0% Scenario{vm=java, trial=0, benchmark=M2} 91,64 ns; σ=5,12 ns @ 10 trials 50% Scenario{vm=java, trial=0, benchmark=M1} 57,38 ns; σ=2,51 ns @ 10 trials benchmark ns linear runtime M2 91,6 ============================== M1 57,4 ==================
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With