C# StringBuilder Memory

Letters of the alphabet: ABC

StringBuilder stores character data in memory. It can reduce the complexity of your program's object model. Instead of storing strings separately, we can store them together. This improves performance at the cost of some logical changes.

Memory usage results for StringBuilder

List:          4.7 MB
StringBuilder: 4.0 MB

This C# article shows how much memory StringBuilder uses. It compares StringBuilder to List.

Program

Note

First, this program compares a List that stores many instances of strings to a StringBuilder that contains that same string data. The List retains the object model and keeps all strings on the managed heap throughout its existence, while the StringBuilder combines the strings into a single object, reducing the workload of the garbage collector. This shows the memory savings that can be attained by changing the representation of your data models.

Program that tests StringBuilder memory usage [C#]

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

class Program
{
    static StringBuilder _builder;
    static List<string> _list;

    static void Main()
    {
	//
	// Get start memory.
	//
	long bytes1 = GC.GetTotalMemory(true);
	//
	// Allocate a list or StringBuilder of many strings.
	// ... Comment out one of these lines to one method.
	//
	_list = GetList();
	_builder = GetBuilder();
	//
	// Results.
	//
	long bytes2 = GC.GetTotalMemory(true);
	Console.WriteLine(bytes2 - bytes1);
    }

    static List<string> GetList() // Allocate list of strings
    {
	List<string> list = new List<string>();
	for (int i = 0; i < 100000; i++)
	{
	    string value = Path.GetRandomFileName();
	    list.Add(value);
	}
	return list;
    }

    static StringBuilder GetBuilder() // Allocate StringBuilder of strings
    {
	StringBuilder builder = new StringBuilder();
	for (int i = 0; i < 100000; i++)
	{
	    string value = Path.GetRandomFileName();
	    builder.Append(value);
	}
	return builder;
    }
}

Output: It prints the memory usage increase between two garbage collections.

Description. The program defines three methods in the Program class: the Main entry point, a method that generates a List containing one hundred thousand random strings, and a method that generates a StringBuilder containing one hundred thousand random strings concatenated. The program should be modified to only run one of the two latter methods at a time.

List type.

List of strings. The GetList method in the program will generate a large list of string instances. All of the strings in the List will be allocated separately on the managed heap, and the garbage collector will have to keep track of the 100,000 strings on the heap as well as the List's internal buffer. This imposes a penalty on many garbage collection passes.

List Examples

Measuring memory usage of StringBuilder. The GetBuilder method allocates a StringBuilder instance and appends 100,000 strings to a single buffer inside the StringBuilder. Because of internal layout of the StringBuilder and its representation as a logical array, each of the string instances will not need to exist. They will have no roots accessible in the managed heap and the garbage collector will free them. This means that the StringBuilder version of the program saves the trouble of managing 100,000 strings.

.NET Framework information

Results. Here we note the results of executing this program on the .NET Framework and a 32-bit operating system kernel. When the program uses the GetList method only, it allocates 4,924,452 bytes on the managed heap. When the program uses the GetStringBuilder method only, it allocates 4,194,456 bytes on the heap. In summary, the StringBuilder representation of the data saves 729,996 bytes or 713 KB.

Capacity

Programming tip

The capacity value can be passed as the integer argument to the StringBuilder constructor. Be aware that the StringBuilder ToString method will be forced to copy the buffer again if it determines the buffer is much too large, so extra-large capacities will reduce performance.

StringBuilder Capacity Test

Summary

The C# programming language

We looked at an example of the StringBuilder type and its allocation of memory in the C# language. We saw how the efficient representation of data in a StringBuilder can greatly reduce memory usage for certain programs, by reducing the complexity of the object model in memory. We also noted the capacity system in the StringBuilder type.

StringBuilder Secrets
.NET