How to use StringBuilder wisely?
Modifying immutable structures like string
s must be done by copying the structure, and by that, consuming more memory and slowing the application's run time (also increasing GC
time, etc...).
StringBuilder
comes to solve this problem by using the same mutable object for manipulations.
However:
when concatenating a string
in compile time as the following:
string myString = "123";
myString += "234";
myString += "345";
it will actually compile to something like that:
string myString = string.Concat("123", "234", "345");
this function is faster than working with StringBuilder
for the number of string
s entering the function is known.
so for compile-time-known string
concatenations you should prefer string.Concat()
.
as for unknown number of string
like in the following case:
string myString = "123";
if (Console.ReadLine() == "a")
{
myString += "234";
}
myString += "345";
Now the compiler can't use the string.Concat()
function, however, StringBuilder
appears to be more efficient in time and memory consumption only when the concatenation is done with 6-7 or more strings
.
Bad practice usage:
StringBuilder myString = new StringBuilder("123");
myString.Append("234");
myString.Append("345");
Fine practice usage (note that if
is used):
StringBuilder myString = new StringBuilder("123");
if (Console.ReadLine() == "a")
{
myString.Append("234");
}
myString.Append("345");
Best practice usage (note that while
loop is used):
StringBuilder myString = new StringBuilder("123");
while (Console.ReadLine() == "a")
{
myString.Append("234"); //Average loop times 4~ or more
}
myString.Append("345");
A string
is an immutable class. You cannot modify it, only create new strings
.
So when you write result += a;
you have three separate strings
in memory at that point: a
, the old value of result
and the new value. Of course this is absolutely fine if you only concatenate a limited number of strings
. If you do that in a for
loop iterating over a large collection it can become a problem.
The StringBuilder
class offers improved performance in these cases. Instead of creating new strings
to store the result of the concatenation it uses the same object. So if you use stringBuilder.Append(a);
you never have the equivalent of the "old value of result
".
This memory efficiency comes with a price of course. When only concatenating a small number of strings
a StringBuilder
is often less efficienct with regards to speed since it had more overhead compared to the immutable string
class.
One thing to keep in mind is that when you need the intermediate strings then StringBuilder
can become less efficient since calling .ToString()
on it creates a new copy of the string
.
The reason is because strings
are immutable. When concatenating a string
you create a new string
. So, when you need to concatenate many strings
you create a lot of objects
. This doesn't cost much in terms of memory, as each string
is used once. But it does give extra work for the GC
.
StringBuilder
however uses the same object
each time, but it does so at the expense of ease of use.