- Frugal Cafe
- Posts
- FC31: You Need a StringBuilder cache
FC31: You Need a StringBuilder cache
You may even need to replace string.Format calls
In .Net Framework, string.Format is implemented by renting a StringBuilder from internal StringBuilder cache, calling StringBuilder.Format, converting to string, and then release the builder.
There are a few issues with the internal StringBuilder cache:
It’s internal to mscorlib.dll, so applications can’t use it.
The StringBuilder cached is stored in thread-static variable, one builder per thread. So nested usage is not using cached builder.
The code was written long time ago, builders with more than 360 characters are rejected on returning. So large string formatting is not optimized.
If you’re using StringBuilder a lot, for example for logging, you need to build your own StringBuilder cache. I was about to write yet another version but found out it’s already supported by Microsoft.Extensions.ObjectPool. So actual implementation is slightly modified version of the one in the Roslyn code base (C# compiler and analyzers), so it’s well tested.
Here is how to set it up:
Now we can add a few extension methods to replace string.Format calls:
Performance test (it’s designed to generate a string longer than 360 characters):
Result:
The DIY version is 29.85% faster, and removes 68% allocations.
Source code: FrugalCafe/Common/StringBuilderExtensions.cs at master · ProfFrugal/FrugalCafe (github.com).
string.Format in .Net Code is now using a new string builder called ValueStringBuilder. That will be another discussion topic.