【发布时间】:2017-06-30 20:12:58
【问题描述】:
我有一个基准:
@BenchmarkMode(Mode.Throughput)
@Fork(1)
@State(Scope.Thread)
@Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS, batchSize = 1000)
@Measurement(iterations = 40, time = 1, timeUnit = TimeUnit.SECONDS, batchSize = 1000)
public class StringConcatTest {
private int aInt;
@Setup
public void prepare() {
aInt = 100;
}
@Benchmark
public String emptyStringInt() {
return "" + aInt;
}
@Benchmark
public String valueOfInt() {
return String.valueOf(aInt);
}
}
这是结果:
Benchmark Mode Cnt Score Error Units
StringConcatTest.emptyStringInt thrpt 40 66045.741 ± 1306.280 ops/s
StringConcatTest.valueOfInt thrpt 40 43947.708 ± 1140.078 ops/s
它表明将空字符串与整数连接比调用 String.value(100) 快 30%。 我知道 "" + 100 转换为
new StringBuilder().append(100).toString()
并应用了-XX:+OptimizeStringConcat 优化,使其速度更快。我不明白为什么valueOf 本身比串联慢。
有人可以解释到底发生了什么以及为什么 "" + 100 更快。 OptimizeStringConcat 有什么魔力?
【问题讨论】:
-
"" + 100对于编译器来说可能更清楚地识别为常量...... -
其中之一是方法调用。另一个,编译器可以随心所欲地编译。
-
@LouisWasserman 它未编译为常量。编译为
StringBuider()构造。 -
JIT 通常不会在较小的运行中发挥作用。你给了基准什么样的热身?
-
我同意这里的情况似乎并非如此。由于我在上面链接到的讨论,一般情况下不一定如此,在未来的编译器版本中也不一定如此。
标签: java performance microbenchmark