Java String.replaceFirst性能与算法替换
假设我想用“zzz”替换字符串中第一个出现的“yyy”。String.replaceFirst似乎是一个完美的解决方案Java String.replaceFirst性能与算法替换,java,Java,假设我想用“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); } 通常最重要的事情是编写清晰简单的代码。就您的性
str = str.repaceFirst("yyy", "zzz");
但是否存在性能问题?以下解决方案对性能是否有影响
int i = s.indexOf("yyy");
if (i != -1) {
str = str.substring(0, i) + "zzz" + s.substring(i + 3);
}
通常最重要的事情是编写清晰简单的代码。就您的性能和需要维护代码的人员而言,第一个选项是最好的
如果你确定调用频繁,意味着你占用的时间太长,那么你可以考虑使用更复杂的编码。除非你已经衡量过它有多大的不同,否则我认为这只是一个猜测。在这种情况下,第二行可能是一个选项
顺便说一句,可能有更快的方法,例如使用StringBuilder,而不是根据上下文创建字符串。通常最重要的是编写清晰简单的代码。就您的性能和需要维护代码的人员而言,第一个选项是最好的
如果你确定调用频繁,意味着你占用的时间太长,那么你可以考虑使用更复杂的编码。除非你已经衡量过它有多大的不同,否则我认为这只是一个猜测。在这种情况下,第二行可能是一个选项
顺便说一句,可能会有更快的方法,例如使用StringBuilder,而不是根据上下文创建字符串。我编写了测试性能的代码。请使用适当的参数在您的机器上运行它以测试它。命令行接受一个从0到1的double
,它表示测试输入与插入“yyy”
子字符串的比率
方法论
生成长度为50、100、500、1000等的5000个随机字符串在5000个字符串中,有一定比例的字符串在随机位置插入序列“yyy”。(由于生成方法的原因,字符串将只包含“yyy”
的一个实例(如果有),但我认为这不是问题)。对于(字符串长度)和(方法)的每个组合,我运行测试30次,并取平均值
测试了以下3种方法:
replaceFirst
:
public static String replaceFirstApproach(String input) {
return input.replaceFirst("yyy", "zzz");
}
子字符串
:
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;
}
}
replaceFirst
的方法总是最慢的。当未找到“yyy”
子字符串时,其速度比其他两种方法慢3-10倍。当可以找到“yyy”
子字符串时,它仍然比子字符串方法慢3倍,比StringBuilder方法慢1.5倍
当可以找到“yyy”
子字符串且字符串很长时,将字符串与+
和子字符串
连接的方法比StringBuilder
快2倍
不过,这里的用例是相当本地化的。尽管子字符串
方法速度更快,但除非您进行密集的字符串处理,否则所获得的收益微不足道。。请使用适当的参数在您的机器上运行它以测试它。命令行接受一个从0到1的double
,它表示测试输入与插入“yyy”
子字符串的比率
方法论
生成长度为50、100、500、1000等的5000个随机字符串在5000个字符串中,有一定比例的字符串在随机位置插入序列“yyy”。(由于生成方法的原因,字符串将只包含“yyy”
的一个实例(如果有),但我认为这不是问题)。对于(字符串长度)和(方法)的每个组合,我运行测试30次,并取平均值
测试了以下3种方法:
replaceFirst
:
public static String replaceFirstApproach(String input) {
return input.replaceFirst("yyy", "zzz");
}
子字符串
:
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;
}
}
结果
该程序在JVM7、Windows7上运行。这些数字是在微秒内处理一批5000个随机字符串的平均时间
插入子字符串的0%“yyy”
插入子字符串的50%“yyy”
插入子字符串的100%“yyy”
长度| 50 100 500 1000 5000
--------------|-------------------------------------------------------
替换第一| 22984 31302 103640 192179 892965
子串| 7846 11494 37093 58544 258356
StringBuilder | 11113 24499 66164 121784 592664
结论
使用replaceFirst
的方法总是最慢的。当未找到“yyy”
子字符串时,其速度比其他两种方法慢3-10倍。当可以找到“yyy”
子字符串时,它仍然比子字符串方法慢3倍,比StringBuilder方法慢1.5倍
方法
Length | 50 100 500 1000 5000
--------------|-------------------------------------------------------
replaceFirst | 20318 28387 95967 176051 845799
substring | 6840 9940 27469 47218 198464
StringBuilder | 8794 13272 50498 94644 470656
Length | 50 100 500 1000 5000
--------------|-------------------------------------------------------
replaceFirst | 22984 31302 103640 192179 892965
substring | 7846 11494 37093 58544 258356
StringBuilder | 11113 24499 66164 121784 592664