Java 8:字符串连接操作会对性能产生重大影响

我正在阅读Java-8中引入的新添加的现有function。 新增加到String类的一个简单特性是对我很有吸引力 – 这就是String Join方法 。

例:

String.join(" ", "AZY","BAX"); // returns AZY BAX 

为了好奇,我通过编写一个简单的java代码检查了这个function的性能(执行时间)

 public static void main(String[] args) { long start = System.nanoTime(); String abc= String.join(" ,"AZY","BAX" … // joining 1000 words of size 3 char; long diff = System.nanoTime() - start; System.out.println(" Java 8 String Join " + diff); start = System.nanoTime(); abc= "AZY"+"BAX"+"CBA"+ … // adding 1000 word of size 3 char; diff = System.nanoTime() - start; System.out.println(" Tranditional " + diff); start = System.nanoTime(); new StringBuilder().append("AZY").append("BAX").appe… // appending 1000 word of size 3 char; diff = System.nanoTime() - start; System.out.println(" String Builder Append " + diff); } 

结果对我来说并不那么令人兴奋(在neno sec的时间)

 Java 8 String Join 1340114 Tranditional 59785 String Builder Append 102807 

复杂性是o(n) – 事实上它是(n *单个元素长度的大小)

其他性能指标(记忆等)我没有测量过。

我的问题是:

  1. 我的测量有什么不对(大多数时候我相信jdk家伙)
  2. 将“join”API添加到String类的目的是什么?
  3. 是否有可用的Java 8性能分析

首先要做的事情。 这不是你如何微桌面Java

阅读如何在Java中编写正确的微基准测试? 第一。 你的号码完全不相关,所以让我们忽略它们。

看第二个例子:

 abc= "AZY"+"BAX"+"CBA"+... 

这看起来像编译时常量给我。 这个String将在编译时连接在一起,没有任何基准测试。 这是一个无用的比较,因为StringBuilderString.join是连接非编译时常量的String

继续比较StringBuilderString.join 。 看一下源代码:

 public static String join(CharSequence delimiter, CharSequence... elements) { Objects.requireNonNull(delimiter); Objects.requireNonNull(elements); // Number of elements not likely worth Arrays.stream overhead. StringJoiner joiner = new StringJoiner(delimiter); for (CharSequence cs: elements) { joiner.add(cs); } return joiner.toString(); } 

这使用StringJoinerStringJoiner只是在引擎盖下使用StringBuilder ,因此两者是等价的。

查看代码通常比尝试和基准性能更具信息性。 即使你做正确的基准测试。

值得注意的是,你的第一个方法,使用join ,将“1000” String连接到“”(空格)上。 而您的StringBuilder方法只是将它们一起附加。 这两个不一样。

String.join方法的重点是你可以这样做:

 String.join(", ", "a", "b", "c") // result is "a, b, c" 

使用StringBuilder您必须添加更多代码。