Understanding the difference between the String
type and StringBuilder
class is really important particularly when you have a massive number of String
s (thousands or millions) to be assigned within a loop.
If you do a normal string
concatenation in such long loops, you will end up in a performance issue and will wreak havoc in your application, especially when you have a low-resource hosting or your application is running on your client’s machine, and you never know and can never tell what are the machine specs on which your app will be running.
It is always crucial to make sure your coding is ideally optimized and properly tested in terms of memory and CPU consumption.
In this article, I will be explaining the difference between using String
and StringBuilder
when dealing with your string
values. and in which cases you should never use String
. and other cases where StringBuilder
is not the optimal solution.
To give you a proper performance difference, I will be showcasing you a performance bench-marking between the usage of String
and StringBuilder
when looping over a huge list of string
s and concatenating the looped values. And finally, I will provide you the equation to calculate the memory usage of your string
and other built-in methods to do this calculation for you.
String
A String
is basically an immutable sequence of characters. Each character is a Unicode character in the range U+0000 to U+FFFF. Immutable means that its state cannot be modified after it is created.
Thus, if you assign a value to a string
then reassign. The first value will stay in the memory and a new memory location will be assigned to accept the new value.
Let’s take these string
allocations for example:
String string1 = "Coding";
String string2 = "Sonata";
String string3;
string3 = string1 + " " + string2;
This leads to 4 memory addresses to be allocated: Coding, Sonata, [EmptyString] , and the Concatenation between Coding and Sonata
When using the above method for a specific purpose or when you know the number of string
s to be concatenated at compile time will be few, then the wasted memory will be negligible, however, this will generate a big issue when in a loop with lots of iterations, where a string
is adding (Concatenating) to itself another string
or value, it is just constantly reallocating, in other words, it is copying to a new memory location when the memory manager can’t expand the requested amount in place. At this point, the amount of memory required (or wasted) and the processing time used for the creation of the numerous objects may become a bottleneck in the application.
This case is mostly common when, for instance, dynamically generating a TABLE and its content, or building an XML document. With this type of scenario in mind, Microsoft included the StringBuilder
class in .NET.
StringBuilder
The StringBuilder
class provides the developer with a set of methods that allows manipulation of a mutable string
of characters, it can be used when you want to modify a string
without creating a new object, thus eliminating the overhead or bottleneck issue of the normal String
concatenation.
Using the StringBuilder
class can boost performance when concatenating many strings together in a loop.
The following is a list of a few operations that can be performed to manipulate a string
using the StringBuilder
Class in .NET.
Append
: Appends information to the end of the current StringBuilder
. AppendFormat
: Replaces a format specifier passed in a string
with formatted text. Insert
: Inserts a string
or object
into the specified index of the current StringBuilder
. Remove
: Removes a specified number of characters from the current StringBuilder
. Replace
: Replaces a specified character at a specified index.
Tips for Using String and StringBuilder
- Use
StringBuilder
when you’re concatenating string
s in a very long loop or in a loop within an unknown size – especially if you don’t know for sure (at compile time) how many iterations you’ll make through the loop. For example, reading a file a character at a time, building up a string
as you go. - Use String Concatenation operator when you can specify everything which needs to be concatenated in one statement. (If you have an array of things to concatenate, consider calling
String.Concat
explicitly – or String.Join
if you need a delimiter.), avoid using the (+=
) or the normal (+
) for string
s concatenation. - If you need the intermediate results of the concatenation for something other than feeding the next iteration of concatenation,
StringBuilder
isn’t going to help you. For instance, if you build up a full name from a first name and a last name, and then add a third piece of information (the nickname, maybe) to the end, you’ll only benefit from using StringBuilder
if you don’t need the (first name + last name) string
for other purpose (as we do in the example which creates a Person
object).
Bench-marking String vs StringBuilder
To benchmark the difference between String
and StringBuilder
, I prepared a simple program to measure the performance of a huge list of string
s when processed through a loop. I’ve used the Visual Studio’s diagnostics tool that displayed the CPU process percentage as well as the memory consumption.
The below code declares a gigantic list of 200K string
s containing string
s starting from ‘1000
’ and upwards.
List<String> hugeList = Enumerable.Range(1000, 200000).Select(n => n.ToString()).ToList();
And here is the code that we loop through this list using the string
concatenation operation (+=
) :
String concatResult = "";
foreach (String value in hugeList)
{
concatResult += value;
}
While running the code, you will notice the diagnostics tool for Visual Studio will start monitoring the memory and CPU activity.
Notice when using the String
concatenation operator +=
, even though we are updating the concatResult
variable within the loop, because String
object is immutable, it will not replace its value in the memory but it will create a new one keeping the old one intact.
So there is performance overkill when having a long loop on a String
object with the +=
concatenation operator.
Processing this list with the string
concatenation operator +=
took 2 minutes 30 seconds which is massive time and very high resource usage due to creating high number of String
objects in memory.
Now let’s boost the performance, and build our gigantic list of string
s in the loop using the correct methodology, the StringBuilder
class.
The below code defines a StringBuilder
object, and then appends the string
being looped. And after that, using the ToString()
method on the stringBuilder
’s object instance, the result of appending all the string
s in the huge list can be retrieved anywhere.
StringBuilder stringBuilder = new StringBuilder();
String stringBuilderResult = "";
foreach (String s in hugeList)
{
stringBuilder.Append(s);
}
stringBuilderResult = stringBuilder.ToString();
Note in the below screenshot, the total processing time for building the 200K string
object, is 99ms only.
Have you just noticed the significantly enormous difference between using String
and StringBuilder
in such huge lists?
Bottom line: Use only StringBuilder when you want to concatenate (or build) a String when you have a large list or list of dynamic size.
Calculating String Size in Bytes
The equation to know the size of String
, for a Unicode string
with a maximum length of 2,147,483,647 characters, is as follows:
80 + [16 * Length] bits
Example:
Dim _StringSample As String = "Aramex" ‘6 Characters
Then using the string
equation:
80 + (16 * 6) = 176 Bits
Same equation divided by 8, will get us the size in bytes:
(10 + [2 * Length] bytes) = 10 + (2 * 6) = 22 Bytes
Other easier and straightforward methods can include:
System.Text.Encoding
– This provides methods to convert string
to bytes. Then use the Length
property to get the size in bytes directly.
Also, the below method can be used:
Encoding.GetByteCount(String) as Integer
Where you pass the string
you like and it then returns the length in Bytes.
Conclusion
I hope I was able to showcase the difference between String
and StringBuilder
, and in which cases you should use any of which. Always make sure to properly understand the data structures when using data types, especially when it comes to the String
objects, since they are immutable (cannot be changed or modified).
If you think you’ve learned something new from my article, please feel free to like and share it with your peers. And if you think there was any wrong information, please let me know.