为什么StringBuilder链接模式sb.append(x).append(y)比常规sb.append(x)更快; sb.append(Y)? [英] Why is the StringBuilder chaining pattern sb.append(x).append(y) faster than regular sb.append(x); sb.append(y)?

查看:690
本文介绍了为什么StringBuilder链接模式sb.append(x).append(y)比常规sb.append(x)更快; sb.append(Y)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个显示非常奇怪结果的微基准测试:

I have a microbenchmark that shows very strange results:

@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 Chaining {

    private String a1 = "111111111111111111111111";
    private String a2 = "222222222222222222222222";
    private String a3 = "333333333333333333333333";

    @Benchmark
    public String typicalChaining() {
        return new StringBuilder().append(a1).append(a2).append(a3).toString();
    }

    @Benchmark
    public String noChaining() {
        StringBuilder sb = new StringBuilder();
        sb.append(a1);
        sb.append(a2);
        sb.append(a3);
        return sb.toString();
    }
}

我期待两个测试的结果都是相同或至少非常接近。但是,差异几乎是5倍:

I'm expecting the results of both tests to be the same or at least very close. However, the difference is almost 5x:

# Run complete. Total time: 00:01:41

Benchmark                  Mode  Cnt      Score     Error  Units
Chaining.noChaining       thrpt   40   8538.236 ± 209.924  ops/s
Chaining.typicalChaining  thrpt   40  36729.523 ± 988.936  ops/s

有人知道这是怎么回事吗?

Does anybody know how that is possible?

推荐答案

字符串连接 a + b + c 是Java程序中非常频繁的模式,因此HotSpot JVM有一个特殊的优化对于它: -XX:+ OptimizeStringConcat 默认情况下为ON。

String concatenation a + b + c is a very frequent pattern in Java programs, so HotSpot JVM has a special optimization for it: -XX:+OptimizeStringConcat which is ON by default.

HotSpot JVM识别 new StringBuilder()。append()... append()。toString()字节码中的模式,并将其转换为优化的机器代码,而无需调用实际的Java方法,也无需分配中间对象。即这是一种复合JVM内在函数。

HotSpot JVM recognizes new StringBuilder().append()...append().toString() pattern in the bytecode and translates it to the optimized machine code without calling actual Java methods and without allocating intermediate objects. I.e. this is a kind of compound JVM intrinsic.

这是此优化的源代码

另一方面方, sb.append(); sb.append(); ...... 未经特别处理。这个序列的编译就像常规的Java方法调用一样。

On the other side, sb.append(); sb.append(); ... is not handled specially. This sequence is compiled just like a regular Java method calls.

如果你用 -XX重新运行基准测试:-OptimizeStringConcat ,两种变体的性能相同。

If you rerun the benchmark with -XX:-OptimizeStringConcat, the performance will be the same for both variants.

这篇关于为什么StringBuilder链接模式sb.append(x).append(y)比常规sb.append(x)更快; sb.append(Y)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆