C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
And: The second version, Method2, references a static StringBuilder field and then clears it each time.
Note: The StringBuilder field will remain allocated in one part of memory throughout all calls to Method2.
Method that creates new StringBuilder: C#
static string Method1()
{
StringBuilder builder = new StringBuilder();
foreach (string value in _array)
builder.Append(value);
return builder.ToString();
}
Method that uses cached StringBuilder: C#
static StringBuilder _builder = new StringBuilder();
static string Method2()
{
StringBuilder builder = _builder;
builder.Clear();
foreach (string value in _array)
builder.Append(value);
return builder.ToString();
}
Also: Fewer allocations occur for the StringBuilder itself, not just its buffer.
C# program that tests StringBuilder cache
using System;
using System.Diagnostics;
using System.Text;
class Program
{
static string Method1()
{
StringBuilder builder = new StringBuilder();
foreach (string value in _array)
builder.Append(value);
return builder.ToString();
}
static StringBuilder _builder = new StringBuilder();
static string Method2()
{
StringBuilder builder = _builder;
builder.Clear();
foreach (string value in _array)
builder.Append(value);
return builder.ToString();
}
static string[] _array = { "dot", "net", "Codex", "string", "array" };
const int _max = 1000000;
static void Main()
{
Method1();
Method2();
// Version 1: use new StringBuilder each time.
var s1 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
Method1();
}
s1.Stop();
// Version 2: reuse a single StringBuilder instance.
var s2 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
Method2();
}
s2.Stop();
Console.WriteLine(s1.Elapsed.TotalMilliseconds);
Console.WriteLine(s2.Elapsed.TotalMilliseconds);
Console.Read();
}
}
Output
140.0784 New StringBuilder (Method1)
84.4145 Cached StringBuilder (Method2)
Warning: This can reduce performance. A slowdown occurs when the buffers are large and clearing them is slower than allocating new ones.
And: Relying on the garbage collector may in this case be faster than using this kind of cache.
Note: Thanks to Alex Lupu for helping improve the benchmark on this page. Thanks to Kimmo Keskinen for noting an error.