Array Collections File String Windows VB.NET Algorithm ASP.NET Cast Class Compression Convert Data Delegate Directive Enum Exception If Interface Keyword LINQ Loop Method .NET Number Regex Sort StringBuilder Struct Switch Time Value

Once created a string cannot be changed. A StringBuilder can be changed as many times as necessary. It yields astonishing performance improvements. It eliminates millions of string copies. Many C# programs append or replace strings in loops. There the StringBuilder type becomes a necessary optimization.
As an introduction, this program shows how the StringBuilder type is used to build up a larger buffer of characters. You can call the Append method on the StringBuilder instance to add more and more data.
Program that uses StringBuilder [C#]
using System;
using System.Text;
class Program
{
static void Main()
{
StringBuilder builder = new StringBuilder();
// Append to StringBuilder.
for (int i = 0; i < 10; i++)
{
builder.Append(i).Append(" ");
}
Console.WriteLine(builder);
}
}
Output
0 1 2 3 4 5 6 7 8 9Next, let's look at some of the essential methods on the StringBuilder type in the base class library. The methods shown here will allow you to use it effectively in many programs, appending strings and lines. This example does not show a loop, and it is not ideal as a program, but it is for demonstration purposes.
Program that uses StringBuilder [C#]
using System;
using System.Text;
using System.Diagnostics;
class Program
{
static void Main()
{
// 1.
// Declare a new StringBuilder.
StringBuilder builder = new StringBuilder();
// 2.
builder.Append("The list starts here:");
// 3.
builder.AppendLine();
// 4.
builder.Append("1 cat").AppendLine();
// 5.
// Get a reference to the StringBuilder's buffer content.
string innerString = builder.ToString();
// Display with Debug.
Debug.WriteLine(innerString);
}
}
Output
The list starts here:
1 cat
New keyword. It uses the new keyword for StringBuilder. Use the new keyword to make your StringBuilder. This is different from regular strings. StringBuilder has many overloaded constructors.
Append. Continuing on, it calls the instance Append method. This method adds the contents of its arguments to the buffer in the StringBuilder. Every argument to StringBuilder will automatically have its ToString method called.
AppendAppendLine. It calls AppendLine, which does the exact same thing as Append, except with a newline on the end. Next, Append and AppendLine call themselves. This shows terse syntax with StringBuilder. Finally, ToString returns the buffer. You will almost always want ToString. It will return the contents as a string.
AppendLine
StringBuilder will make your appends go faster usually, but there's another benefit. There is a concept of memory pressure, meaning that the more temporary objects created by your app, the more often garbage collection runs. StringBuilder creates fewer temporary objects and adds less memory pressure. We show the memory usage of a StringBuilder after garbage collection occurs.
StringBuilder MemoryNext, you can use StringBuilder to replace characters in loops. First convert the string to a StringBuilder, and then call StringBuilder's methods to do these operations. This is faster because the StringBuilder type uses character arrays internally, not unchangeable strings.
Program that uses Replace [C#]
using System;
using System.Text;
class Program
{
static void Main()
{
StringBuilder builder = new StringBuilder(
"This is an example string that is an example.");
builder.Replace("an", "the"); // Replaces 'an' with 'the'.
Console.WriteLine(builder.ToString());
Console.ReadLine();
}
}
Output
This is the example string that is the example.
When you don't have a loop, generally you should avoid StringBuilder. There is lots of logic in StringBuilder that will be slow on very small operations. StringBuilder can make your code more cumbersome. Here we look at some potential problems with using StringBuilder in problems.
When to consider char arrays. Character arrays, specified as char[], are vastly simpler, but your code must be more precise. If you know a maximum or absolute size of your output string, and your requirements are simple, use char arrays.
Char ArrayCommon mistake. Many developers make a very specific StringBuilder mistake that reduces speed by about 40%. Don't use the + operator on strings within a StringBuilder. It will simply draw in the slowness of strings, resulting in many temporary assignments and copies to the managed heap.
StringBuilder MistakeImmutable strings. Immutable indicates that the data being pointed at is not changeable. To see an example of an immutable object in the C# language, try to assign to a character in a string. This causes a compile-time error, because the string type does not define a set accessor. However, character arrays can be changed. Internally, StringBuilder uses mutable char arrays for its buffer.
The AppendFormat method on the StringBuilder type is very important and deserves a closer look. It can be used to add text to your StringBuilder based on a pattern. You can use substitution markers to fill fields in this pattern.
AppendFormat draws in regular strings and substitutions. Internally, many versions of AppendFormat in the .NET Framework are implemented with StringBuilder instances. It is usually faster to call Append repeatedly with all the required parts. However, the syntax of AppendFormat can be clearer to read and maintain in some programs.
AppendFormatYou can use StringBuilder in a simple loop. As I have noted, almost always your StringBuilder will be used in a loop. This can be a foreach, for, or while loop. Here's another example of StringBuilder, but in a foreach loop.
foreachProgram that uses foreach [C#]
using System;
using System.Text;
class Program
{
static void Main()
{
string[] items = { "Cat", "Dog", "Celebrity" };
StringBuilder builder2 = new StringBuilder(
"These items are required:").AppendLine();
foreach (string item in items)
{
builder2.Append(item).AppendLine();
}
Console.WriteLine(builder2.ToString());
Console.ReadLine();
}
}
Output
These items are required:
Cat
Dog
Celebrity
You will find that StringBuilder defines an instance method Equals that can be used to compare the capacities and contents of two StringBuilders. It is important to use this method because you can avoid lots of error-prone code that you write yourself. There are some subtleties to Equals, however, which we look into.
EqualsHow can you clear the data inside your StringBuilder that you have already appended? Sometimes it is best to allocate a new StringBuilder instance; other times, you can assign the Length property to zero or use the Clear method from the .NET Framework 4.0.
ClearLet's explore how you can use the StringBuilder type as an argument. This is a significant optimization because it will avoid converting back and forth to strings. The example shows StringBuilder parameters and reusing the same StringBuilder. Strings alone would be hugely slower in many cases.
Program that creates many StringBuilders [C#]
using System;
using System.Text;
class Program
{
static string[] _items = new string[]
{
"cat",
"dog",
"giraffe"
};
/// <summary>
/// Append to a new StringBuilder and return it as a string.
/// </summary>
static string A1()
{
StringBuilder b = new StringBuilder();
foreach (string item in _items)
{
b.AppendLine(item);
}
return b.ToString();
}
static void Main()
{
// Called in loop.
A1();
}
}
Program that uses StringBuilder argument [C#]
using System;
using System.Text;
class Program
{
static string[] _items = new string[]
{
"cat",
"dog",
"giraffe"
};
/// <summary>
/// Append to the StringBuilder param, void method.
/// </summary>
static void A2(StringBuilder b)
{
foreach (string item in _items)
{
b.AppendLine(item);
}
}
static void Main()
{
// Called in loop.
StringBuilder b = new StringBuilder();
A2(b);
}
}
Results
Version 1: 5039 ms
Version 2: 3073 msIt is possible to use the indexer on your StringBuilder instance to access or change certain characters. This syntax is the same as the syntax for accessing characters in a string instance. The following example shows how you can test characters in a StringBuilder and also change them. We change the string "cat" to "rat".
Program that uses StringBuilder indexer [C#]
using System;
using System.Text;
class Program
{
static void Main()
{
StringBuilder builder = new StringBuilder();
builder.Append("cat");
// Write second letter.
Console.WriteLine(builder[1]);
// Change first letter.
builder[0] = 'r';
Console.WriteLine(builder.ToString());
}
}
Output
a
ratYou can use the Remove method on the StringBuilder type remove a range of characters by index from the internal StringBuilder buffer. As with other StringBuilder methods, this just rearranges the internal buffer and does not allocate new data. Here, we remove characters starting at index 4. We remove three characters.
Program that uses Remove on StringBuilder [C#]
using System;
using System.Text;
class Program
{
static void Main()
{
StringBuilder builder = new StringBuilder("Dot Net Perls");
builder.Remove(4, 3);
Console.WriteLine(builder);
}
}
Output
Dot PerlsAnother neat trick with the StringBuilder Append method is that you can append a substring directly from another string. You do not need to call Substring before calling Append. This will improve performance in some situations.
Append SubstringThe ToString method implementation for the StringBuilder type has optimizations where it will not actually copy the data in certain situations. It's apparent that the StringBuilder has a lot of optimizations that would be hard for us to duplicate without a lot of development work.
ToString
You may be getting this exception if you are putting too much data in your StringBuilder. The maximum number of characters in a StringBuilder is equal to Int32.MaxValue. I suggest you check for infinite loops or other serious problems.
int.MaxValue ExampleOften, you need to Append a string to your StringBuilder directly after allocating it. We found that when you specify that string in the constructor, the overall performance is somewhat improved. Calling Append separately takes more time.
Version 1 [C#]
var builder = new StringBuilder(10);
builder.Append("Cat");
Version 2 [C#]
var builder = new StringBuilder("Cat", 10);
Times
38.80 ns
32.47 nsThe StringBuilder is mainly a performance optimization for the string type in certain cases. We demonstrate the performance and memory usage of StringBuilder; they can be useful for learning when StringBuilder is superior.
StringBuilder Cache Tip
StringBuilder Data Types
StringBuilder Optimization Tip
StringBuilder Performance
Integer Append OptimizationNote: Using a capacity on your StringBuilder is also very important for performance.
Capacity. Internally, the StringBuilder manages a capacity buffer where the data is stored. We elaborate on how the internal buffer is resized, and provides a graph to aid understanding.
StringBuilder Capacity Test
Let's review the members on the StringBuilder type in the .NET Framework base class library. This document only shows some of the StringBuilder members. The Replace, Insert and Remove methods are very important, even though they are less common than Append.
Append
This is the most basic StringBuilder method. You can use Append with a format string,
a string, or other data types such as chars and integers. Nothing other than
the argument's string representation is appended.
AppendFormat
Appends string using the formatting syntax available in string.Format.
This can improve code clarity.
EnsureCapacity
This rarely is useful for changing the capacity.
This is an optimization you can use.
Insert
Very similar to the Replace method.
Used to add characters at an index.
Remove
Essentially the same as the Remove method on string.
Avoids character array copying.
See the example on this page.
Replace
Replaces one string of characters with another.
This has some performance advantages over the Replace method on the string type.
ToString
Internally converts the buffer to a string type.
Often does not perform any additional allocations.
You can read and write string data with the StringReader and StringWriter types. StringReader you a unique way to loop over and read lines or blocks from a source string, as shown in this example. StringWriter, on the other hand, can be used as a backing store for the HtmlTextWriter.
StringReader StringWriter
We saw ways you can effectively use StringBuilder in your C# application. StringBuilder can improve the performance of your program, even if you misuse it; by using it optimally, though, results are much better. We recommend that you use StringBuilder as a parameter instead of calling ToString frequently.