When I looked at decompiled .NET assemblies to see some internal elements, I noticed an interesting StringBuilderCache class used by several frameworks:
internal static class StringBuilderCache { [ThreadStatic] private static StringBuilder CachedInstance; private const int MAX_BUILDER_SIZE = 360; public static StringBuilder Acquire(int capacity = 16) { if (capacity <= 360) { StringBuilder cachedInstance = StringBuilderCache.CachedInstance; if (cachedInstance != null && capacity <= cachedInstance.Capacity) { StringBuilderCache.CachedInstance = null; cachedInstance.Clear(); return cachedInstance; } } return new StringBuilder(capacity); } public static void Release(StringBuilder sb) { if (sb.Capacity <= 360) { StringBuilderCache.CachedInstance = sb; } } public static string GetStringAndRelease(StringBuilder sb) { string result = sb.ToString(); StringBuilderCache.Release(sb); return result; } }
We can find an example of use, for example, in the string.Format method:
public static string Format(IFormatProvider provider, string format, params object[] args) { ... StringBuilder stringBuilder = StringBuilderCache.Acquire(format.Length + args.Length * 8); stringBuilder.AppendFormat(provider, format, args); return StringBuilderCache.GetStringAndRelease(stringBuilder); }
Although itβs pretty smart and Iβll probably remember that caching scheme, I wonder why MAX_BUILDER_SIZE so small? Having installed it, let it install 2kB, wouldnβt it be better? This would prevent the creation of large instances of StringBuilder with fairly low memory overhead.
Konrad Kokosa
source share