В нескольких ответах мягко говорилось, что я должен снять свой пух и сам разобраться, поэтому ниже приведены мои результаты. Я думаю, что настроение в целом идет вразрез с этим сайтом, но если вы хотите, чтобы что-то было сделано правильно, вы могли бы также сделать ....:)
Я изменил опцию # 1, чтобы воспользоваться предложением @Ty для использования StringBuilder.Length = 0 вместо метода Remove. Это сделало код этих двух вариантов более похожим. Два различия теперь заключаются в том, находится ли конструктор для StringBuilder в цикле или вне его, и опция # 1 теперь использует метод Length для очистки StringBuilder. Обе опции были настроены для работы над массивом outputStrings с 100 000 элементов, чтобы сборщик мусора выполнял какую-то работу.
Пара ответов предлагает подсказки, чтобы посмотреть на различные счетчики PerfMon и тому подобное и использовать результаты, чтобы выбрать опцию. Я провел небольшое исследование и в конечном итоге использовал встроенный Performance Explorer выпуска Visual Studio Team Systems Developer, который у меня есть на работе. Я нашел вторую запись в серии из нескольких частей, в которой объясняется, как ее настроить здесь . По сути, вы подключаете модульный тест, чтобы указать на код, который вы хотите профилировать; пройти через мастера и некоторые конфигурации; и запустите профилирование модульного теста. Я включил распределение объектов .NET и показатели времени жизни. Результаты профилирования трудно отформатировать для этого ответа, поэтому я поместил их в конце. Если вы скопируете и вставите текст в Excel и слегка помассируете их, они будут читабельными.
Опция # 1 - это наиболее эффективная память, поскольку она заставляет сборщик мусора выполнять немного меньше работы и выделяет половину памяти и экземпляров для объекта StringBuilder, чем опция # 2. Для повседневного кодирования идеально подойдет вариант №2.
Если вы все еще читаете, я задал этот вопрос, потому что Вариант № 2 заставит детекторы утечки памяти опытного разработчика на C / C ++ стать баллистическими. Большая утечка памяти произойдет, если экземпляр StringBuilder не будет освобожден перед переназначением. Конечно, мы, разработчики C #, не беспокоимся о таких вещах (пока они не подпрыгнут и не укусят нас). Спасибо всем !!
ClassName Instances TotalBytesAllocated Gen0_InstancesCollected Gen0BytesCollected Gen1InstancesCollected Gen1BytesCollected
=======Option #1
System.Text.StringBuilder 100,001 2,000,020 100,016 2,000,320 2 40
System.String 301,020 32,587,168 201,147 11,165,268 3 246
System.Char[] 200,000 8,977,780 200,022 8,979,678 2 90
System.String[] 1 400,016 26 1,512 0 0
System.Int32 100,000 1,200,000 100,061 1,200,732 2 24
System.Object[] 100,000 2,000,000 100,070 2,004,092 2 40
======Option #2
System.Text.StringBuilder 200,000 4,000,000 200,011 4,000,220 4 80
System.String 401,018 37,587,036 301,127 16,164,318 3 214
System.Char[] 200,000 9,377,780 200,024 9,379,768 0 0
System.String[] 1 400,016 20 1,208 0 0
System.Int32 100,000 1,200,000 100,051 1,200,612 1 12
System.Object[] 100,000 2,000,000 100,058 2,003,004 1 20