Joh*_*ohn 2 java performance stringbuilder concatenation
我做了一个性能测试
String test="";
Date st = new Date();
logger.info("start "+(new Date()).toString());
for(int i = 0;i<100000;i++) {
test += "test";
}
logger.info("end "+(new Date()).toString());
test="";
StringBuilder sb = new StringBuilder(test);
logger.info("start Sb "+(new Date()).toString());
for(int i = 0;i<100000;i++) {
sb.append("test");
}
test = sb.toString();
logger.info("end sb "+(new Date()).toString());
Run Code Online (Sandbox Code Playgroud)
结果是
start Fri Jun 30 10:34:42 KRAT 2017
end Fri Jun 30 10:34:55 KRAT 2017
start Sb Fri Jun 30 10:34:55 KRAT 2017
end sb Fri Jun 30 10:34:55 KRAT 2017
Run Code Online (Sandbox Code Playgroud)
相差13秒!!!
但我到处都看到“+”运算符更快的标语,因为从 java 1.6 开始它就得到了优化。怎么了?我哪里弄错了?
+是通过分配一个StringBuilder并调用append来实现的。以下代码行是等效的:
String s = new StringBuilder().append(string1).append(string2).append(string3).toString();
String s = string1 + string2 + string3;
Run Code Online (Sandbox Code Playgroud)
不幸的是,编译器不擅长识别循环中的字符串连接链,因此以下代码片段也是等效的。
String test="";
for(int i = 0;i<100000;i++) {
test += "test";
}
String test="";
for(int i = 0;i<100000;i++) {
test = new StringBuilder().append(test).append("test").toString();
}
Run Code Online (Sandbox Code Playgroud)
请注意,后者在每次循环迭代中分配一个新的 StringBuilder 并每次对结果调用 toString 。您可以通过查看“javac Test.java && javap -c Test”生成的字节码来验证这一点。根据经验,如果您的字符串连接可以写为一个表达式,则最好使用 + 运算符以提高可读性。
关于编写这些基准测试的旁注:测试每个替代方案的顺序会影响它们的性能。您可能应该为每个版本编写两个单独的主要方法,以便您的测试是独立的。另外,您对名为 test 的变量做了很多工作,但没有在任何地方使用它。编译器可以自由地优化您的第一个 for 循环,因为 test 的值随后立即重置。
| 归档时间: |
|
| 查看次数: |
1333 次 |
| 最近记录: |