Using StringBuilders instead of Strings

Published

I’m currently working on a Racing Game in Unity (as mentionned in my Racetrack Generator post) and while I usually take great pains to avoid Garbage Collection, I had gone a bit fast when recording completion time for laps.

Basically, since I was prototyping I was using the naïve implementation of concatenating Strings. Part of the code went like this:

mTextComponent.text = record.mMinutes.ToString().PadLeft(2, '0') + ":" + record.mSeconds.ToString().PadLeft(2, '0') + ":" + record.mMilliseconds.ToString().PadLeft(3, '0');  

So the problem here is obvious: I am casting 3 variables (integers to be precise) to string, and then padding them with zeroes.

Why is this a problem? Well, first of all handling Strings is costly, no matter what you are doing with them so it’s good practice to avoid creating new strings whenever possible. Second, we know that Strings are actually arrays of Chars so they are allocated to the heap and are also immutable.

Since I am casting integers to strings, this means I am making 3 allocations per frame. What’s more I am also padding these strings, and then concatenating them: this means I am doing at least 3 * 2 + 1 allocations, and therefore creating a lot of garbage which must be collected.

Considering all this, it would be a much better practice to use a StringBuilder to handle my String manipulations.

Quoting the Microsoft documentation:

Consider using the StringBuilder class under these conditions:
- When you expect your app to make an unknown number of changes to a string at design time (for example, when you are using a loop to concatenate a random number of strings that contain user input).
- When you expect your app to make a significant number of changes to a string.

The StringBuilder has several properties which make it an interesting class to use:

  • It is mutable, so we can avoid allocating by mutating the underlying array of characters
  • You can set a maximal capacity to the array
  • It is also possible to append to the char array. Additional memory will be allocated as necessary if max capacity is reached.
  • It is part of the default System library of C#. You only need to add “using System.Text;” to be able to use the StringBuilder class

So, these are some really useful properties, definitely consider using StringBuilder instead of String if you’re manipulating Strings.

Still, most functions in Unity will be expecting you to pass a String as input instead of a StringBuilder so you still won’t be able to completely avoid Strings. But at least, your code will be more efficient in terms of memory usage!