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

2022-09-03 03:31:09

我正在浏览Java-8中引入的新添加的现有功能。新添加到 String 类中的一个简单功能对我而言非常有吸引力 - 这就是 String Join 方法

例:

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

出于好奇,我通过编写一个简单的java代码检查了此功能的性能(执行时间)

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秒为单位的时间)

Java 8 String Join     1340114
Tranditional             59785
String Builder Append   102807

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

其他性能指标(内存等)我没有测量。

我的问题是:

  1. 我的测量有什么问题吗(大多数时候我相信jdk的人)
  2. 将“加入”API 添加到字符串类的目的是什么
  3. 有没有针对Java 8的性能分析可用

答案 1

首先要做的事情。这不是你微板凳Java的方式

首先阅读如何用 Java 编写正确的微基准测试?你的数字是完全无关紧要的,所以让我们忽略它们。

看看第二个例子:

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

这些对我来说就像编译时间常量。这将在编译时连接,并且不会有任何可基准测试的内容。这是一个无用的比较,因为or的全部意义在于连接不是编译时间常数的s。StringStringBuilderString.joinString

继续比较 和 。查看源代码: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();
}

这将使用 .A只是简单地使用引擎盖下,所以两者是等价的。StringJoinerStringJoinerStringBuilder

查看代码通常比尝试对性能进行基准测试要丰富得多。即使您正确进行了基准测试。

同样值得注意的是,您的第一个方法,带有 ,连接了 “” (空格) 上的 1000 s。而您的方法只是将它们追加在一起。这两者是不一样的。joinStringStringBuilder

该方法的要点是您可以执行以下操作:String.join

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

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


答案 2

推荐