Post

StringBuilder is just a Cargo Cult (sometimes)

Can you think of top 10 questions in .NET developer interview? I bet one of them is about string builders. Like “how would you concatenate multiple strings?”. With the correct answer “I’d use StringBuilder. Because, you know, string is immutable, allocations, blah, blah, blah…”. And if you pretend to be an experienced developer, your code has 0 (zero) concatenations via +.

Even when it comes to join 2 (3, 4, 5, …) literals or constants, they still use StringBuilder. Or course, it’s less effective, because such concatenations usually happen during compilation (constants are embedded into code as literals).

But what about regular strings? Should one always use StringBuilder? I’ve prepared a small benchmark, using BenchMarkDotNet (source code is available on GitHub) that shows that when the number of strings is less than 20, StringBuilder has no advantage over +. Even more, when number of items is less that 10, + has better performance. And this is exactly the most used scenario of string concatenation. If you have more than 10 items, you’d most likely use the loop with StringBuilder, or String.Join() or (if you’re crazy badass) IEnumerable.Aggregate().

Here are results from tests running on my machine:

1
2
3
4
5
6
7
8
9
BenchmarkDotNet=v0.10.11, OS=Windows 10 Redstone 3 [1709, Fall Creators Update] (10.0.16299.192)
Processor=Intel Core i7-4720HQ CPU 2.60GHz (Haswell), ProcessorCount=8
Frequency=2533208 Hz, Resolution=394.7564 ns, Timer=TSC
.NET Core SDK=2.1.2
  [Host]     : .NET Core 2.0.3 (Framework 4.6.25815.02), 64bit RyuJIT
  DefaultJob : .NET Core 2.0.3 (Framework 4.6.25815.02), 64bit RyuJIT


MethodNumberOfItemsMeanErrorStdDevMedian
StringBuilderAction2885.5 ns7.824 ns7.319 ns885.3 ns
StringConcatenationAction2770.6 ns6.802 ns6.362 ns771.4 ns
StringBuilderAction51,785.5 ns10.304 ns9.639 ns1,784.6 ns
StringConcatenationAction51,674.5 ns20.619 ns18.278 ns1,672.6 ns
StringBuilderAction103,215.0 ns63.250 ns62.120 ns3,186.8 ns
StringConcatenationAction103,313.1 ns102.415 ns85.521 ns3,283.2 ns
StringBuilderAction205,951.5 ns48.102 ns40.167 ns5,937.8 ns
StringConcatenationAction206,947.7 ns34.813 ns29.071 ns6,940.4 ns
StringBuilderAction5014,997.1 ns347.515 ns985.841 ns14,672.7 ns
StringConcatenationAction5022,794.2 ns474.567 ns1,291.094 ns22,303.9 ns
StringBuilderAction10027,873.3 ns481.219 ns375.704 ns27,864.9 ns
StringConcatenationAction10059,897.8 ns1,948.882 ns3,091.133 ns59,045.8 ns

There is another, poor man’s benchmark available on dotnetfiddle.net. It might be less accurate, but + always wins.

Having that we can conclude that using StringBuilder to just concatenate a couple of strings is nothing but a Cargo Cult. More code and less performance…

Happy coding!

This post is licensed under CC BY 4.0 by the author.