pit*_*chr 7 java string benchmarking pool concatenation
我正在尝试一些关于String Pool的性能基准测试.但是,预计结果不会出现.
我做了3个静态方法
我的期望是(1.最快 - > 3.最慢)
但基准测试显示"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
...
Run Code Online (Sandbox Code Playgroud)
这是代码:
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");
}
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么"Te"+"st"的表现比"Test"快吗?JVM在这里做了一些优化吗?谢谢.
Mar*_*ers 10
"Te" + "st"是一个编译器时间常量表达式,因此在运行时的行为与简单的行为没有区别"Test".任何性能损失将在尝试编译时,而不是在尝试运行时.
通过使用javap -c StringPoolPerformance以下方法反汇编编译的基准类,可以很容易地证明这一点:
public static long perform1();
Code:
...
7: ldc #3; //int 1000000
9: if_icmpge 21
12: ldc #5; //String Test
14: astore_3
15: iinc 2, 1
...
public static long perform2();
Code:
...
7: ldc #3; //int 1000000
9: if_icmpge 21
12: ldc #5; //String Test
14: astore_3
15: iinc 2, 1
...
Run Code Online (Sandbox Code Playgroud)
方法的字节代码完全相同!这由Java语言规范15.18.1指定:
除非表达式是编译时常量表达式(第15.28节),否则将新创建String对象(第12.5节).
您遇到的基准差异可能是由于典型的可变性或因为您的基准不完美.看到这个问题:如何在Java中编写正确的微基准测试?
你打破一些值得注意的规则:
perform1()是在创建一百万个对象的测试后始终正在运行时).| 归档时间: |
|
| 查看次数: |
333 次 |
| 最近记录: |