Java OutputStream 打印速度

Java OutputStream printing speed

假设我必须用逗号分隔值打印数组 arr。现在,我正在做以下事情:

for(int i = 0;i<arr.length;i++) {
    System.out.print(arr[i] + ",");
}

但是,对于较大的 arr 长度,我想知道这是否真的很慢。我想到的第二种方法是使用 StringBuilder,构建最终输出字符串并且只使用 1 个打印语句。那值得吗?权衡将是更复杂的代码。

如果重要的话,我想要一个打印到控制台和打印到文件的答案。

这段代码效率不高,因为每次计算时都必须实例化一个新的字符串arr[i] + ",",这需要分配一个新的内存槽,并在完成后用垃圾收集器丢弃旧字符串。

Dave Newton 给出的解决方案是打印数组的最有效方法。我用一个包含 20 000 个元素的数组做了一个小基准测试(我在我的小型 PC 中可以选择的最大数量,因为当数组太大时显示数组往往会扭曲计算时间):

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        String[] array = new String[20000];
        Arrays.fill(array, "A");

        long t0 = System.currentTimeMillis();

        /* Test 1 : using a for loop */
        for (int i = 0; i < array.length; i++)
            System.out.print(array[i] + ",");
    
        System.out.println();
        long t1 = System.currentTimeMillis();

        /* Test 2 : using a for-each loop */
        for (String a : array)
            System.out.print(a + ",");
    
        System.out.println();
        long t2 = System.currentTimeMillis();

        /* Test 3 : using String.join */
        System.out.println(String.join(",", array));
        long t3 = System.currentTimeMillis();
    
        System.out.println("Test 1 : " + (t1 - t0) + "ms");
        System.out.println("Test 2 : " + (t2 - t1) + "ms");
        System.out.println("Test 3 : " + (t3 - t2) + "ms");
    }
}

我得到以下结果:

Test 1 : 110ms
Test 2 : 93ms
Test 3 : 0ms

This website说明了原因。 String.join 生成一个 StringJoiner 实例,它将字符存储在 StringBuilder.

StringBuilder 作为缓冲区;在缓冲区中附加 Strings 然后显示结果比多次实例化 2 Strings 的总和更有效。