假设我想用“zzz”替换字符串中“yyy”的第一个出现。 String.replaceFirst似乎是一个完美的解决方案
str = str.repaceFirst("yyy", "zzz");
但是有性能问题吗?以下解决方案在性能方面有何不同?
int i = s.indexOf("yyy");
if (i != -1) {
str = str.substring(0, i) + "zzz" + s.substring(i + 3);
}
答案 0 :(得分:2)
通常最重要的是编写清晰简单的代码。就您的性能和必须维护代码的人而言,第一种选择是最好的。
如果您确定经常调用它并且意味着您花费的时间太长,那么您可能会考虑使用更复杂的编码。除非你已经测量了它产生的差异,否则我认为这只是猜测。在这种情况下,第二行可以是一个选项。
BTW可能有更快的方法,例如使用StringBuilder而不是根据您的上下文创建String。
答案 1 :(得分:1)
我写了some code来测试性能。请使用适当的参数在您的盒子上运行它以进行测试。命令行接受从0到1的double
,表示测试输入与插入"yyy"
子串的比率。
5000随机字符串。 插入5000个字符串的某些百分比时,序列“yyy”处于随机位置。 (由于生成方法,如果有的话,字符串将只包含"yyy"
的单个实例,但我不认为这是一个问题)。对于(字符串长度)和(接近)的每个组合,我运行测试 30 次并取平均值。
测试了以下3种方法:
replaceFirst
:
public static String replaceFirstApproach(String input) {
return input.replaceFirst("yyy", "zzz");
}
substring
:
public static String substringApproach(String input) {
int i = input.indexOf("yyy");
if (i != -1) {
input = input.substring(0, i) + "zzz" + input.substring(i + 3);
}
return input;
}
使用StringBuilder
构造输出字符串:
public static String appendStringBuilder(String input) {
int i = input.indexOf("yyy");
if (i != -1) {
StringBuilder output = new StringBuilder(input.length());
output.append(input, 0, i).append("zzz").append(input, i + 3, input.length());
return output.toString();
} else {
return input;
}
}
该程序在JVM 7,Windows 7上运行。这些数字是在微秒中处理1批5000个随机字符串的平均时间。
插入子字符串"yyy"
Length | 50 100 500 1000 5000 --------------|------------------------------------------------------- replaceFirst | 17389 22718 74194 137285 629438 substring | 4429 7246 13421 18069 78920 StringBuilder | 4604 5615 11509 19093 79366
25%插入子字符串"yyy"
Length | 50 100 500 1000 5000 --------------|------------------------------------------------------- replaceFirst | 18531 24959 78211 146956 692992 substring | 5250 6764 18994 27959 113805 StringBuilder | 5768 8609 23857 45789 205580
插入子字符串"yyy"
Length | 50 100 500 1000 5000 --------------|------------------------------------------------------- replaceFirst | 19833 27648 90932 162558 760558 substring | 6007 8848 21909 37415 154959 StringBuilder | 7075 12095 37765 70038 327171
75%插入子字符串"yyy"
Length | 50 100 500 1000 5000 --------------|------------------------------------------------------- replaceFirst | 20318 28387 95967 176051 845799 substring | 6840 9940 27469 47218 198464 StringBuilder | 8794 13272 50498 94644 470656
插入子字符串"yyy"
Length | 50 100 500 1000 5000 --------------|------------------------------------------------------- replaceFirst | 22984 31302 103640 192179 892965 substring | 7846 11494 37093 58544 258356 StringBuilder | 11113 24499 66164 121784 592664
replaceFirst
的方法总是最慢的。如果未找到"yyy"
子字符串,则比其他2个方法慢3-10倍。当"yyy"
子字符串可以找到时,它仍然比substring
方法慢3倍,StringBuilder
接近1.5倍。
当找到+
子字符串且字符串很长时,将字符串与substring
和StringBuilder
连接的方法比"yyy"
快2倍。
这里的用例非常本地化。虽然substring
方法更快,但除非你进行密集的字符串处理,否则增益是微不足道的。