String concatenation and the myths that go with it

By eidias on (tags: performance, categories: code)

I’ve heard a lot of advice about how I should and how I should not concatenate strings. I’ve stuck to them, but the moment of questioning was inevitable. So I spun up a small app to see what’s what. If you’re interested, read along.

There have always been moments when I wasn’t sure when to use the “+” operator and when not – in a majority of cases I didn’t cause I’ve always been told “don’t do it”. Turns out, it’s not that bad at all, you just need to know (or even better – check) if a particular case is a good one to ‘just add’.

I’m skipping the obvious cases here – if you’re building a big string (and by big I mean something that consists of more than 50 small strings) no doubts here – StringBuilder is your friend and will be the best choice in 99% of cases.

There are 2 cases though that kept me wondering:

  1. What if I need to just combine a couple of small strings, add a prefix or a suffix or maybe an underscore in between
  2. What if I need to create a small string but in a loop

Let’s look at these, but first

The test

The test that gave me the results is a very simple one and definitely not a complete one. I run the mentioned concatenating operations in a loop that iterates 100 000 times. When I mention concatenating in a loop that means that each iteration of the outer loop has an inner loop inside.

Now back to the point.

Prefixes, suffixes and all that small stuff

First of all (probably stating the obvious here), if you’ve ever caught yourself doing something like that:

   1: "a"+"b"+"c"+...

then apart from the fact that it’s well…silly, it doesn’t really bring any performance implications – the compiler is kind enough to make that one string, just like you should.

Now, if you’re concatenating string variables together (not in a loop), a little test of mine showed that if you have less than 28 variables then concatenating with + is faster than using StringBuilder. Anything over 28, StringBuilder wins. So

   1: var s = a + b + c + d;

is faster than

   1: var sb = new StringBuilder();
   2: sb.Append(a);
   3: sb.Append(b);
   4: sb.Append(c);
   5: sb.Append(d);
   6: var s = sb.ToString();

Sticking it in a loop

When doing the same operation as before but in a loop, it turns out, that the number of operations in which the execution time is the same drops – a lot. Another test showed that just 10 iterations in a loop are enough to give StringBuilder the edge. That’s a really low number, so the takeaway here – if using a loop to concatenate a string – use StringBuilder.

Other stuff

There is another way to create a string that is used pretty often – string.Format(). I use it a lot simply because it’s comfortable, but performance wise – it looses all the time. I haven’t been able to find a case in which string.Format() is faster than the “+” operator or using StringBuilder. That means, that I’ll need to stop doing things like

   1: string.Format("{0}{1}{2}", a, b, c)

because it doesn’t make sense.

Conclusions

If you’re adding prefixes, suffixes or combining a small about of strings, don’t fear the “+” operator, use it. If you’re building something bigger – StringBuilder is your friend. If you like string.Format() then be ready to pay the performance price and also - I need to change some habits.

If anyone is interested in the code that I used. Here it is.

Cheers