Luk*_*uth 19 java string-concatenation performance-testing
我目前正在研究String concat选项以及它们对整体性能的惩罚.我的测试用例创造了令我心烦意乱的结果,我不确定我是否会忽略某些东西.
这是交易:"something"+"somethingElse"在java中执行(在编译时)StringBuilder每次完成时都会创建一个新的.
对于我的测试用例,我正在从我的HDD加载一个包含1661行示例数据的文件(经典的"Lorem Ipsum").这个问题不是关于I/O性能,而是关于不同字符串concat方法的性能.
public class InefficientStringConcat {
public static void main(String[] agrs) throws Exception{
// Get a file with example data:
System.out.println("Starting benchmark");
// Read an measure:
for (int i = 0; i < 10; i++){
BufferedReader in = new BufferedReader(
new InputStreamReader(new FileInputStream(new File("data.txt")))
);
long start = System.currentTimeMillis();
// Un-comment method to test:
//inefficientRead(in);
//betterRead(in);
long end = System.currentTimeMillis();
System.out.println("Took "+(end-start)+"ms");
in.close();
}
}
public static String betterRead(BufferedReader in) throws IOException{
StringBuilder b = new StringBuilder();
String line;
while ((line = in.readLine()) != null){
b.append(line);
}
return b.toString();
}
public static String inefficientRead(BufferedReader in) throws IOException {
String everything = "", line;
while ((line = in.readLine()) != null){
everything += line;
}
return everything;
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,两种测试的设置相同.结果如下:
使用inefficientRead()-method:
Starting benchmark
#1 Took 658ms
#2 Took 590ms
#3 Took 569ms
#4 Took 567ms
#5 Took 562ms
#6 Took 570ms
#7 Took 563ms
#8 Took 568ms
#9 Took 560ms
#10 Took 568ms
Run Code Online (Sandbox Code Playgroud)
使用betterRead()-method
Starting benchmark
#1 Took 42ms
#2 Took 10ms
#3 Took 5ms
#4 Took 7ms
#5 Took 16ms
#6 Took 3ms
#7 Took 4ms
#8 Took 5ms
#9 Took 5ms
#10 Took 13ms
Run Code Online (Sandbox Code Playgroud)
我正在运行测试而没有额外的参数到java命令.我从2009年初开始运行MacMini3,1和Sun JDK 7:
[luke@BlackBox ~]$ java -version
java version "1.7.0_09"
Java(TM) SE Runtime Environment (build 1.7.0_09-b05)
Java HotSpot(TM) Client VM (build 23.5-b02, mixed mode)
Run Code Online (Sandbox Code Playgroud)
这让我觉得非常沉重.我在测量这个时做错了什么,或者这应该发生?
Jon*_*eet 23
我在测量这个时做错了什么,或者这应该发生?
它应该发生.构建重复使用字符串连接长字符串是一个已知的性能反模式:每个级联必须创建一个新的字符串拷贝原始字符串的,也是一个复制的附加字符串.你最终获得了O(N 2)的表现.当您使用时StringBuilder,大多数时候您只是将附加字符串复制到缓冲区中.有时缓冲区需要耗尽空间并需要扩展(通过将现有数据复制到新缓冲区),但这种情况不会经常发生(由于缓冲区扩展策略).
有关详细信息,请参阅我关于字符串连接的文章 - 这是一篇非常古老的文章,所以早期StringBuilder,但基本原理没有改变.(基本上StringBuilder就像StringBuffer,但没有同步.)
| 归档时间: |
|
| 查看次数: |
3726 次 |
| 最近记录: |