【发布时间】:2012-08-22 20:45:51
【问题描述】:
我正在尝试一些关于字符串池的性能基准测试。然而,结果并不出人意料。
我做了3个静态方法
- perform0() 方法...每次都创建一个新对象
- perform1() 方法...字符串文字“Test”
- perform2() 方法...字符串常量表达式“Te”+“st”
我的预期是(1. 最快 -> 3. 最慢)
- “测试”因为字符串池
- “Te”+“st”,因为字符串池,但比 1 慢,因为 + 运算符
- new String(..) 因为没有字符串池。
但基准测试显示“Te”+“st”比“Test”略快。
new String(): 141677000 ns
"Test" : 1148000 ns
"Te"+"st" : 1059000 ns
new String(): 141253000 ns
"Test" : 1177000 ns
"Te"+"st" : 1089000 ns
new String(): 142307000 ns
"Test" : 1878000 ns
"Te"+"st" : 1082000 ns
new String(): 142127000 ns
"Test" : 1155000 ns
"Te"+"st" : 1078000 ns
...
代码如下:
import java.util.concurrent.TimeUnit;
public class StringPoolPerformance {
public static long perform0() {
long start = System.nanoTime();
for (int i=0; i<1000000; i++) {
String str = new String("Test");
}
return System.nanoTime()-start;
}
public static long perform1() {
long start = System.nanoTime();
for (int i=0; i<1000000; i++) {
String str = "Test";
}
return System.nanoTime()-start;
}
public static long perform2() {
long start = System.nanoTime();
for (int i=0; i<1000000; i++) {
String str = "Te"+"st";
}
return System.nanoTime()-start;
}
public static void main(String[] args) {
long time0=0, time1=0, time2=0;
for (int i=0; i<100; i++) {
// result
time0 += perform0();
time1 += perform1();
time2 += perform2();
}
System.out.println("new String(): " + time0 + " ns");
System.out.println("\"Test\" : " + time1 + " ns");
System.out.println("\"Te\"+\"st\" : " + time2 + " ns");
}
}
有人能解释为什么“Te”+“st”的执行速度比“Test”快吗? JVM在这里做了一些优化吗?谢谢。
【问题讨论】:
-
编译器不会只是合并两个常量吗?
-
字符串 "Te","st" 是文字,所以编译器会在优化阶段将它们更改为 "Test" 吗?我不知道
-
改变你调用perform1和perform2的顺序,看看你是否仍然得到相同的结果。
-
上下文切换可能会导致线程等待
-
您可能想阅读以下内容:Anatomy of a flawed microbenchmark
标签: java string concatenation benchmarking pool