4

UPDATE: I tested by concatenating with the + operator and the performance was almost the same as by doing it with a StringBuilder (results in the end). This suggests, as some of you have mentioned in the answers, that the slower performance is due to the format analysis.

Conclusion: Java's printf() is not a efficient method for concatenating and printing strings. Either the + operator or preferably a StringBuilder should be used for better performance.

Does Java's printf() use slow concatenation when creating Strings? i.e. does it create a new String after appending each element to the final String?

I tested using a StringBuilder to create the string I obtained a performance improvement of about 4 times faster run time. This part of the program was called thousands of times in my program.

The only differences between the two tests were the following blocks of code:

1) printf() (0.8 seconds):

System.out.printf("%d %d %d %d %d %d\n", nums[a], nums[b],
    nums[c], nums[d], nums[e], nums[f]);

2) StringBuilder + println() (0.2 seconds):

StringBuilder sb = new StringBuilder();
sb.append(nums[a]);
sb.append(' ');
sb.append(nums[b]);
sb.append(' ');
sb.append(nums[c]);
sb.append(' ');
sb.append(nums[d]);
sb.append(' ');
sb.append(nums[e]);
sb.append(' ');
sb.append(nums[f]);                  
System.out.println(sb.toString());

3) + operaror + println() (0.22 seconds):

System.out.println(nums[a] + " " + nums[b] + " " + nums[c] + " " + nums[d] + " "
                          + nums[e] + " " + nums[f]);
Juan Martinez
  • 2,520
  • 2
  • 16
  • 8
  • 6
    My guess would be that the concatenation is irrelevant but that the analysis of the format is what takes time. – chrylis -cautiouslyoptimistic- Apr 15 '15 at 15:40
  • You could concatenate the string yourself to see if that makes any difference. If not than @chrylis is most likely correct, otherwise, your probably correct however I wouldn't image creating a new string would cause that much of a performance drain. The difference is most likely within the format analysis that takes place in printf(). – CalebB Apr 15 '15 at 15:44
  • 2
    Well, if you take a look at the source code, it does a lot more things. ([link](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/util/Formatter.java#Formatter.format%28java.util.Locale%2Cjava.lang.String%2Cjava.lang.Object%5B%5D%29)) – Bubletan Apr 15 '15 at 15:44
  • 2
    My guess is that it's irrelevant. This is a micro-optimization that's more likely to be overwhelmed by stuff you're doing in your code, latency, etc. – duffymo Apr 15 '15 at 16:57
  • @duffymo Most of the time most of the code is performance-wise irrelevant. If you server mostly generates some simple CSV files, it may get relevant. However, it's a pity that `String.`format` isn't more optimized. – maaartinus Apr 15 '15 at 17:42
  • define *bad* and *many*, this is pretty subjective and useless as question as it stands –  Apr 15 '15 at 17:44
  • Thank you for your comments. I made the test by concatenating with the '+' operator and the results were similar to using a StringBuilder. So it's pretty clear that the slower performance is due to the format analysis as some of you said. – Juan Martinez Apr 15 '15 at 20:26
  • *"This question has been asked before and already has an answer."* - **Right. And the answer has a score of 49 despite being completely wrong!** – maaartinus Apr 15 '15 at 20:47

1 Answers1

1

Does Java's printf() use slow concatenation when creating Strings?

Definitely no. The concatenation is fine.

However, it's pretty slow because of the analysis of the format strings. There are quite a few possibilities and a lot of branching and what else.

It would be nearly(*) possible to parse the string upfront and use a List<FormatItem> where each FormatItem would take care of one argument (als also add all the preceding fixed text). Once I did something like this and it was 2+ times faster.

(*) It gets more complicated by things like %3$s.

maaartinus
  • 44,714
  • 32
  • 161
  • 320