I recently encountered an idiom I haven\'t seen before: string assembly by StringWriter and PrintWriter. I mean, I know how to use them, but I\'ve always used StringBuilder
in this link : http://nohack.eingenetzt.com/java/java-stringwriter-vs-stringbuilder the author shows that the StringWriter is even slightly faster than the StringBuilder.and also said : "So when bigger amounts of data come into play the StringWriter clearly shows its superiority in performance over the StringBuilder."
I see two advantages of the PrintWriter method: (1) You don't have to add " + newline" at the end of every single line, which actually results in shorter code if you have a lot of writing to do. (2) You don't have to call System.getProperty(); you let the PrintWriter worry about what the newline character should be.
StringWriter is what you use when when you want to write to a string, but you're working with an API that expects a Writer or a Stream. It's not an alternative, it's a compromise: you use StringWriter only when you have to.
Okay, since the answers seem to stress the stylistic reasons for preferring one over the other, I decided to gen up a timing test.
Edit: Following robinst's comment above, I now have three methods: one which does PrintWriter(StringWriter)-style appending, and two which use StringBuilder: one with the append of the newline inside the append (as in the original: builder.append(thing + newline);
), and the other does a separate append (as above: builder.append(thing).append(newline);
).
I followed my usual benchmarking scheme: call the methods several (1000 in this case) times first to give the optimizer time to warm up, then call each a large number of times (100,000 in this case) in alternating sequence, so that any changes in the workstation's runtime environment are more fairly distributed, and run the test itself several times and average the results.
Oh, and of course the number of lines created and the length of the lines is randomized but held to be the same for each pair of calls, because I wanted to avoid any possible effects of buffer size or line size on the results.
The code for this is here: http://pastebin.com/vtZFzuds
Note: I have not yet updated the pastebin code to reflect the new test.
TL,DR? The average results for 100,000 calls to each method are quite close:
That's so close that the timing is nearly irrelevant to me, so I'm going to continue doing things the way I always did: StringBuilder(with separate append), for stylistic reasons. Of course, while working in this established and mature codebase, I'll mostly keep to the existing conventions, in order to minimize surprise.
Writers - PrintWriter writes to a stream. It does weird things like suppressing IOExceptions. System.out is one of these. - StringWriter is a Writer that writes to a StringBuffer (similar to ByteArrayOutputStream for OutputStreams)
StringBuilder - and of course StringBuilder is what you want if you are simply want to constructs strings in memory.
Conclusion
Writers by design are meant to push character data out a stream (usually to a file or through a connection) so being able to use Writers to simply assemble strings seems to be a bit of a side effect.
StringBuilder (and its synchronized sibling StringBuffer) are designed to assemble strings (read string bashing). If you look at the StringBuilder API you can see thatnot only can you do vanilla appending but also replace, reverse, insert etc. StringBuilder is your String construction friend.
Stylistically, the StringBuilder
approach is cleaner. It is fewer lines of code and is using a class that was specifically designed for the purpose of building strings.
The other consideration is which is more efficient. The best way to answer that would be to benchmark the two alternatives. But there are some clear pointers that StringBuilder should be faster. For a start, a StringWriter uses a StringBuilder StringBuffer under the hood to hold the characters written to the "stream".