了解.NET内部的StringBuilderCache类配置

Kon*_*osa 8 .net c# stringbuilder .net-internals

当我查看反编译的.NET程序集以查看一些内部结构时,我注意到StringBuilderCache了多个框架方法使用的有趣类:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我们可以在string.Format方法中找到的示例用法:

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);
}
Run Code Online (Sandbox Code Playgroud)

虽然它非常聪明,我肯定会记得这种缓存模式,但我想知道为什么MAX_BUILDER_SIZE这么小?将它设置为,设置2kB,会不会更好?它可以防止StringBuilder以非常小的内存开销创建更大的实例.

Han*_*ant 17

它是一个每线程缓存,因此预计数量较少.最好使用参考源这样的问题,你也会看到评论.看起来像(编辑适合):

    // The value 360 was chosen in discussion with performance experts as a 
    // compromise between using as litle memory (per thread) as possible and 
    // still covering a large part of short-lived StringBuilder creations on 
    // the startup path of VS designers.
    private const int MAX_BUILDER_SIZE = 360;
Run Code Online (Sandbox Code Playgroud)

"VS设计师"有点令人费解.嗯,不是真的,这项工作肯定是为了优化Visual Studio.Neelie Kroes将有一个实地日,如果她发现,欧盟将有另外数十亿美元:)


And*_*bel 5

构建的大多数字符串可能很小,因此使用相对较小的缓冲区大小将覆盖大多数操作,同时不会消耗太多内存.考虑到有一个线程池可能创建了许多线程.如果它们中的每一个都需要高达2kB的缓存缓冲区,它会增加一些内存量.