Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

java

string

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?

like image 504
ScegfOd Avatar asked Feb 06 '17 20:02

ScegfOd


3 Answers

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());
like image 52
Mzf Avatar answered Oct 26 '22 10:10

Mzf


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.

like image 28
Jiri Tousek Avatar answered Oct 26 '22 11:10

Jiri Tousek


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.

like image 26
elirandav Avatar answered Oct 26 '22 09:10

elirandav