Понимание внутренней конфигурации класса StringBuilderCache .NET.

StackOverflow https://stackoverflow.com//questions/20029868

Вопрос

Когда я просматривал декомпилированные сборки .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;
    }
}

Пример использования мы можем найти, например, в 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);
}

Хотя это довольно умно, и я наверняка запомню такой шаблон кэширования, мне интересно, почему MAX_BUILDER_SIZE такой маленький?Настроим, давайте установим 2кБ, не лучше ли?Это помешало бы создавать более крупные StringBuilder экземпляры с довольно небольшими затратами памяти.

Это было полезно?

Решение

Это попоточный кеш, поэтому ожидается небольшое число.Лучше всего использовать Справочный источник по таким вопросам вы также увидите комментарии.Это выглядит так (отредактировано):

    // 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;

«Дизайнеры VS» немного озадачивают.Ну не совсем, наверняка эта работа была проделана для оптимизации Visual Studio.У Нили Крус был бы отличный день, а у ЕС был бы еще один миллиард долларов, если бы она узнала :)

Другие советы

Большинство создаваемых строк, вероятно, имеют небольшой размер, поэтому использование относительно небольшого размера буфера позволит покрыть большую часть операций, не используя при этом слишком много памяти.Учтите, что существует пул потоков, в котором может быть создано множество потоков.Если бы каждый из них занимал до 2 КБ для кэшированного буфера, это увеличило бы некоторый объем памяти.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top