Search code examples
javastringbuilderoutputstream

Java OutputStream printing speed


Suppose I had to print an array arr with comma-separated values. Right now, I am doing the following:

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

However, for large arr lengths, I was wondering if this might be really slow. A second approach I had in mind was using StringBuilder, and constructing the final output string and only using 1 print statement. Would that be worth going for? The tradeoff would be more complicated code.

If it matters, I would like an answer for printing to console and printing to a file.


Solution

  • This code isn't efficient because you have to instantiate a new String each time you calculate arr[i] + ",", which requires to allocate a new memory slot and discard the old string with the garbage collector when it's done.

    The solution given by Dave Newton is the most efficient way to print your array. I've made a little benchmark with an array containing 20 000 elements (the biggest number I can choose in my small PC because displaying the array tends to distort the computing time when the array is too big):

    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");
        }
    }
    

    I have the following results:

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

    This website explains the reason. String.join generates a StringJoiner instance which stores characters in a StringBuilder.

    StringBuilder works as a buffer; appending Strings in a buffer then display the result is way more efficient than instantiating the sum of 2 Strings multiple times.