简体   繁体   中英

Difference between multiple System.out.print() and concatenation

Basically, I was wondering which approach is better practice,

for(int i = 0; i < 10000; i++){
    System.out.print("blah");
}
System.out.println("");

or

String over_9000_blahs = "";
for(int i = 0; i < 10000; i++){
    over_9000_blahs += "blah";
}
System.out.println(over_9000_blahs);

or is there an even better way that I'm not aware of?

You want to use StringBuilder if you're concatenating string in a (larger count) loop.

for(int i = 0; i < 10000; i++){
    over_9000_blahs += "blah";
}

What this does is for each iteration :

  • Creates a new StringBuilder internally with internal char array large enough to accommodate the intermediate result ( over_9000_blahs )
  • Copies the characters from over_9000_blahs into the internal array
  • Copies the characters from "blah"
  • Creates a new String , copying the characters from internal array again

So that is two copies of the increasingly long string per iteration - that means quadratic time complexity.


Since System.out.println() might be synchronized , there's a chance that calling it repeatedly will be slower than using StringBuilder (but my guess would be it won't be slower than concatenating the string in the loop using += ).

So the StringBuilder approach should be the best of the three.

Since you are only writing to the System.out the first approach is better BUT if performance are important to you use the method below ( System.out.println is synchronized and using locking - can read more about it here and here ) .

If you want to use the "big string" later or improve performance, it's cleaner to use StringBuilder . (see below) , anycase String + will translate to StringBuilder by the compiler (more details here )

        StringBuilder stringBuilder = new StringBuilder();
        for(int i = 0; i < 10000; i++){
            stringBuilder.append("bla");
        }
        System.out.println(stringBuilder.toString());

By performance order:

  1. StringBuilder - The fastest. Basically, it just adding the words into a array of characters. When capacity is not enough then it multiply it. Should occur no more than log(10000) times.

  2. System.out.print - It has bad performance comparing to StringBuilder because we need to lock out 10000 times. In addition, print creates new char[writeBufferSize] 10000 times while in the StringBuilder option we do all that 1 time only!

  3. Concatenating strings. Creating many (and later also big ) objects, starting some 'i' the memory management will impact the performance badly.

EDIT:

To be more accurate, because the question was about the difference between option 2 and option 3 and it is very clear why Stringbuilder is fast.

We can say that every iteration in the second approach takes K time, because the code is the same and the length of the string is the same for every iteration. At the end of execution, the second option will take 10000*K time for 10000 iterations. We can't say the same about the third approach because the length of the string is always increasing for each iteration. So the time for allocating the objects and garbage collecting them increasing . What I'm trying to say is that the execution time does not increased linearly in the third option. So it is possible that for low NumberOfIterations we won't see the difference between the two last approaches. But we know that starting a specific NumberOfIterations the second option is always better than the third one.

In this case, I'd say the first one is better. Java uses StringBuilders for string concatenations to increase performance, but since Java doesn't know you are repeatedly doing concatenations with a loop like in the second case, the first case would be better.

If you want only to sysout your values - the result is same.

Second option will create many strings in memory, which GC (Garbage Collector) will take care of. (But in newer versions of Java this problem don't occurs because concating will be transformed behined the scenes to StringBuilder solution below)

If you want use your string later, after sysout, you should check StringBuilder class and append method:

StringBuilder sb = new StringBuilder();
for(int i = 0; i < 10000; i++){
    sb.append("blah");
}
System.out.println(sb);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM