Speeding Up the StringBuilder Using an ObjectPool

If you weren’t already aware, Microsoft .NET features a type known as the ObjectPool, which can significantly enhance performance by pooling objects rather than generating new ones each time they are required. In this article, I will demonstrate how to effectively utilize it with the StringBuilder.

256 Seconds with dotNetDave

To illustrate how to utilize the StringBuilder with an ObjectPool, I’ve produced a new episode of “256 Seconds with dotNetDave.”

The Code

Microsoft .NET includes a type called the ObjectPool that can improve performance by pooling objects instead of creating a new one each time it’s needed. To utilize ObjectPool with StringBuilder, begin by creating the pool as a field, as illustrated below:

private readonly ObjectPool<StringBuilder> _stringBuilderPool = 
    new DefaultObjectPoolProvider().CreateStringBuilderPool();

To utilize it, obtain the StringBuilder from the pool using the Get() method, as demonstrated below:

var sb = this._stringBuilderPool.Get();

Then proceed to use the StringBuilder as usual, as illustrated in this example.

for (var index = 0; index < this._stringArray.Length; index++)
{
    _ = sb.Append(this._stringArray[index]);
}

When the StringBuilder is no longer needed, return it to the pool using the Return() method

_stringBuilderPool.Return(sb);

In the code that I write, I encapsulate these calls with a try/finally block and invoke Return() in the finally block to guarantee that the object is always returned to the pool.

Benchmark Results

As evident in the benchmark report, utilizing the ObjectPool from a field proves to be more efficient in all scenarios, except for the Insert() method. To elaborate AppendFormat() demonstrates an overall performance improvement of 1.008 times, AppendLine() showcases a 1.13 times enhancement, AppendJoin() exhibits a 1.08 times improvement, and Append() registers a 1.051 times efficiency gain. However, it’s noteworthy that Insert() appears to be 1.17 times less performant, though the reason for this disparity is not immediately apparent.

Allocations: Append(): 504 – 135,856 bytes. AppendFormat(): 728 – 196,690 bytes. AppendJoin(): 536 – 139,952 bytes. AppendLine(): 568 – 144,048 bytes. Insert(): 2,456 – 274,416 bytes. There is a distinction in the allocation behavior between these four benchmark tests.

Summary

The next time you require the use of a StringBuilder, contemplate utilizing it from an ObjectPool for a notable performance boost! Further performance insights are detailed in my book, “Rock Your Code: Code and App Performance for Microsoft .NET,” available on Amazon.com.

Pick up any books by David McCarter by going to Amazon.com: http://bit.ly/RockYourCodeBooks

One-Time
Monthly
Yearly

Make a one-time donation

Make a monthly donation

Make a yearly donation

Choose an amount

$5.00
$15.00
$100.00
$5.00
$15.00
$100.00
$5.00
$15.00
$100.00

Or enter a custom amount

$

Your contribution is appreciated.

Your contribution is appreciated.

Your contribution is appreciated.

DonateDonate monthlyDonate yearly

If you liked this article, please buy David a cup of Coffee by going here: https://www.buymeacoffee.com/dotnetdave

© The information in this article is copywritten and cannot be preproduced in any way without express permission from David McCarter.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.