Boost Your .NET Projects with Spargine: Simplify StringBuilder Usage with StringBuilderExtensions

Spargine is a collection of open-source assemblies and NuGet packages designed for .NET 10, which I have been developing and maintaining since the release of .NET Framework 2. These assemblies are not only a core part of my projects but are also actively deployed in production environments across several companies I collaborate with.

Get Spargine

You can access the source code and NuGet packages here:

Simplify StringBuilder Usage with Spargine’s StringBuilderExtensions

When performance matters, StringBuilder is already a powerful tool — but writing clean, reusable string-building logic can still get messy fast. That’s where Spargine’s StringBuilderExtensions—part of the DotNetTips.Spargine.Extensions project and NuGet package—steps in.

These extensions streamline common string-building scenarios, reduce repetitive boilerplate, and help prevent subtle bugs, all while keeping performance at the forefront. Whether you’re appending key/value pairs, formatting byte arrays, or joining collections into text, StringBuilderExtensions makes your code clearer, safer, and faster to write.

Key Features of StringBuilderExtensions

The StringBuilderExtensions class is designed for performance and error prevention. Here is a breakdown of its key methods:

  • AppendBytes(byte[] bytes)
    Appends the bytes to the StringBuilder in hexadecimal format, prefixed with ‘0x’ and enclosed in single quotes.
  • AppendKeyValue(string key, string value, bool includeQuotes, bool includeComma)
    Appends a key-value pair to the StringBuilder in a formatted string representation.
  • AppendValues(string separator, IEnumerable<string> values)
    Appends a collection of string values to the StringBuilder, separated by the specified separator.
  • AppendValues(string separator, params ReadOnlyCollection<string> values)
    Appends a collection of string values to the StringBuilder, separated by the specified separator.
  • AppendValues<T, TParam>(string separator, IEnumerable<T> values, TParam param, Action<T, TParam> joinAction)
    Appends a collection of values to the StringBuilder, separated by the specified separator, using a custom join action that takes an additional parameter.
  • AppendValues<T, TParam1, TParam2>(string separator, IEnumerable<T> values, TParam1 param1, TParam2 param2, Action<StringBuilder, T, TParam1, TParam2> joinAction)
    Appends a collection of values to the StringBuilder, separated by the specified separator, using a custom join action that takes two additional parameters.
  • AppendValues<T>(string separator, IEnumerable<T> values, Action<T> joinAction)
    Appends a collection of values to the StringBuilder, separated by the specified separator, using a custom join action.
  • ClearSetCapacity(int capacity)
     Clears the StringBuilder and sets its capacity to the specified value.
  • SetCapacity(int capacity)
    Sets the capacity of the StringBuilder to the specified value.

Summary

StringBuilderExtensions brings clarity, consistency, and efficiency to everyday StringBuilder operations. By replacing repetitive append logic with clean extension methods, your code becomes easier to read, easier to maintain, and less prone to mistakes — without sacrificing performance.

And if you want to take execution speed even further, combine these extensions with an ObjectPool<StringBuilder> to dramatically reduce memory allocations in high-throughput scenarios.

Bottom line: if you’re using StringBuilder, Spargine’s StringBuilderExtensions is an easy win for cleaner, faster .NET code.

Get Involved!

The success of open-source projects like Spargine relies on community contributions. If you find these updates useful or have ideas for further improvements, I encourage you to contribute by:

  • Submitting pull requests
  • Reporting issues
  • Suggesting new features

Your input is invaluable in making Spargine an even more powerful tool for the .NET community.

If you are interested in contributing or have any questions, feel free to contact me via email at dotnetdave@live.com. Your support and collaboration are greatly appreciated!

Thank you, and happy coding!

Speeding Up the StringBuilder Using an ObjectPool

Updated JANUARY 2024

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.”

https://vimeo.com/743169409

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

Make a one-time donation

Your contribution is appreciated.

Donate

Make a monthly donation

Your contribution is appreciated.

Donate monthly

Make a yearly donation

Your contribution is appreciated.

Donate yearly

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

Type your email…

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

September 8, 2022, 8:01 am 0 boosts 0 favorites

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.


Discover more from dotNetTips.com

Subscribe to get the latest posts sent to your email.

Leave a comment

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