StringBuilder vs String concatenation
Instances of String
are immutable in Java and in Groovy too, of course. This isn’t very apparent when the code looks like this
someString += 'new string part'
Under the hood the JVM creates an entirely new String instance and connects that new thing to someString
. Most of the time it is perfectly fine to ignore this implementation detail, but If you have a use case where it is worth having a more efficient approach there is the appropriately named StringBuilder
. It is a mutable sequence of characters - basically a buffer object.
StringBuilder is very fast and consumes less memory than a String while performing concatenations.
The Code Comparasaurus
Here is an example and a performance comparison using StringBuilder:
1 | String stringConcatenation() { |
Give that a run in a GroovyConsole.
Locally if you have Groovy installed groovyConsole
should fire it up. Or there is a web version available over at https://groovyconsole.appspot.com/
Output will vary quite a bit, but here is a fairly average output on the web console I just referred to
1 | They are equivalent strings? true |
Conclusion
Okay, so 500 or 600 % sounds like a lot, but the big caveat is that in absolute terms it isn’t much. Not even in a contrived and somewhat extreme example such as this. Memory usage is almost certainly also significantly lower, but if I were guessing I bet it follows the same pattern - that is, significant in terms of percentage, but probably not significant relative to the memory use of a large JVM application like Spring or Grails. I didn’t have enough ambition today to go about getting an accurate measure on that.
Now if you were using something like Micronaut?!
Here is the other odd thing. JVM manages memory for you. Automatic garbage collection is kinda nice, but I got such wildly varying results with this test case that I can’t help suspect that as the culprit in this case. The variation was especially exaggerated when running via the web console.
1 | They are equivalent strings? true |
One take-away from that high degree of variation; the ol += approach can sometimes, unpredictably, be a lot LOT slower than StringBuilder, so if you need a method with more consistent performance characteristic or throughput then StringBuilder is probably the way to go.