DEV Community

Discussion on: Performance Benchmarking: String and String Builder

Collapse
 
brkerez profile image
Pavel Trka

Not trying to be rude or smart-ass or anything but I may have some tips for better benchmarks ;)

This measurement has few problems so you may be not getting relevant results.

Also I would argue that relevance of micro-benchmarks are limited if you don't measure exactly the thing you're then using in real code. Isolated micro-benchmarks have of course purpose but can mislead as they may not tell you much about real situation where much more things are in play and modern compilers do not make it simpler as they introduce many tricks ;) In other words are you concactenating those numbers of such Strings in this loop in your real code? ;)

I'm not trying to tell that's the only way but I'm always micro-benchmarking with very narrow focus for some particular situation/problem where I need to decide which way to go and even then I'm always very careful about interpreting results.

some tips (see link at the end for deeper info and links) :

  • your benchmark has no warm-up phase, JVM needs it to eliminate class loading effects etc
  • since Java 9, String concatenation handling in JDK is more complicated under the hood than it seems and simple + sign is bad does not longer apply. See openjdk.org/jeps/280 and maybe some additional deep-dive in metebalci.com/blog/digging-into-je... (and many more discoverable by Goole search)
  • don't measure using System.nanoTime(), use some microbenchmark frameworks like JMH

Good tips on java microbenchmarking: stackoverflow.com/questions/504103...

Collapse
 
kaleemniz profile image
Kaleem

These resources are super helpful and great tips thanks for writing such a detailed response.

Collapse
 
cicirello profile image
Vincent A. Cicirello • Edited

@kaleemniz there are a couple issues with your comparison. Check out Pavel's comment above on microbenchmarking frameworks. They handle the warmup phase that your comparison overlooks.

Also, the StringBuilder version isn't entirely fair. Ultimately if using a StringBuilder you'll eventually call toString, but yours does not.

I'd also rather see both versions have only n and the appended character as parameters. And instead of void, return a String. And then use a microbenchmarking framework.

Why this suggestion on returning a string and not passing the StringBuilder as a parameter? The version with repeated + is updating parameter variable which is not observable external to the method due to pass by value, and thus even the final string is subject to garbage collection. While in the StringBuilder version, the calls to append are changing state of the StringBuilder you passed, so those changes are externally observable.