gpt4 book ai didi

java - 字符串池 : "Te" +"st" faster than "Test"?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:10:31 26 4
gpt4 key购买 nike

我正在尝试一些关于字符串池的性能基准。然而,结果并非预期。

我做了3个静态方法

  • perform0() 方法...每次创建一个新对象
  • perform1() 方法 ... 字符串文字“Test”
  • perform2() 方法 ... 字符串常量表达式 "Te"+"st"

我的期望是(1. 最快 -> 3. 最慢)

  1. “测试”因为字符串池
  2. "Te"+"st"因为字符串池,但比 1 慢一点,因为 + 运算符
  3. 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"没有什么不同。任何性能影响都将在尝试编译时发生,而不是在尝试运行时发生。

使用 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
...

方法的字节码完全相同!这是由 Java Language Specification, 15.18.1 指定的:

The String object is newly created (§12.5) unless the expression is a compile-time constant expression (§15.28).

您遇到的基准差异可能是由于典型的可变性或因为您的基准并不完美。看到这个问题:How do I write a correct micro-benchmark in Java?

您违反的一些值得注意的规则:

  1. 您不会丢弃测试内核“预热”迭代的结果。
  2. 您没有启用 GC 日志记录(当 perform1() 总是在创建一百万个对象的测试后立即运行时尤其相关)。

关于java - 字符串池 : "Te" +"st" faster than "Test"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12081170/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com