Why is String concatenation faster than String.valueOf for converting an Integer to a String?
我有一个基准:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | @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); } } |
结果是:
1 2 3 | 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转换成
1 | new StringBuilder().append(100).toString() |
并采用了
正如您所提到的,Hotspot JVM具有识别StringBuilder模式的
通过分析生成的程序集代码,我发现了以下主要区别:
- 优化后的concat不会使为结果字符串创建的
char[] 数组归零,而由Integer.toString 创建的数组在分配后会像其他常规对象一样被清除。 - 优化后的concat通过简单地添加"0"常量将数字转换为字符,而
Integer.getChars 使用带有相关数组边界检查的表查找等。
在执行
顺便说一句,如果取一个更大的数字(例如1234567890),性能差异将可以忽略,因为