Правило, что я следую, -
Использование StringBuilder, когда количество конкатенаций неизвестно во время компиляции.
Так, в Вашем случае каждый StringBuilder только добавлял несколько раз и затем отбрасывался. Это не действительно то же как что-то как
string s = String.Empty;
for (int i = 0; i < 10000; ++i)
{
s += "A";
}
, Где использование StringBuilder решительно улучшило бы производительность, потому что Вы будете иначе постоянно выделять новую память.
Я уверен, что у меня есть другой ответ, где я отправил просто ссылка на мою статью и затем ее сводку, но здесь мы идем снова.
Определенно использование StringBuilder
, когда Вы конкатенируете в нетривиальном цикле - особенно, если Вы не знаете наверняка (во время компиляции), сколько повторений Вы сделаете через цикл. Например, читая файл символ за один раз, создавая строку, когда Вы идете с помощью + =, оператор является потенциально самоубийством производительности.
Определенно используют оператор конкатенации, когда можно (четко) указать все, что должно быть связано в одном операторе. (Если у Вас есть массив вещей связать, рассмотреть вызов String.Concat
явно - или String.Join
при необходимости в разделителе.)
не боятся разбить литералы в несколько связанных битов - результатом будет то же. Можно помочь удобочитаемости путем повреждения длинного литерала в несколько строк, например, без вреда производительности.
, Если Вам нужны промежуточные результаты конкатенации для чего-то другого, чем питание следующего повторения конкатенации, StringBuilder
, не собирается помогать Вам. Например, если Вы создадите полное имя от имени и фамилии, и затем добавите третью информацию (псевдоним, возможно) в конец, то Вы только извлечете выгоду из использования StringBuilder
, если Вам не будет нужно (имя + фамилия) строка для другой цели (как мы делаем в примере, который создает Person
объект).
, Если у Вас просто есть несколько конкатенаций, чтобы сделать, и Вы действительно хотите сделать их в отдельных операторах, это действительно не имеет значения, какой путь Вы идете. То, какой путь более эффективен, будет зависеть от количества конкатенаций размеры строки, включенной, и что приказывает, чтобы они были связаны в. Если Вы действительно полагаете, что часть кода, чтобы быть узким местом производительности, представьте или сравнить его оба пути.
Существует интересная статья об этом законченном в Ужас Кодирования . Jeff получил следующие результаты для 100 000 повторений на двухъядерном Core 2 Duo на 3,5 ГГц:
Simple Concatenation - 606 ms
String.Format - 665 ms
string.Concat - 587 ms
String.Replace - 979 ms
StringBuilder - 588 ms
Мое эмпирическое правило просто.
+
. , По моему опыту, выражения, такие как:
"Id: " + item.id + " name: " + item.name
может быть записан и понят намного более легко, чем:
StringBuilder sb = new StringBuilder();
sb.append("Id: ").append(item.id);
sb.append(" name: ").append(item.name);
(сопровождаемый при помощи строки от sb
, где вышеупомянутое выражение было бы записано), и оно работает одинаково хорошо (подсказка: посмотрите на скомпилированный код для наблюдения почему!)
, С другой стороны, когда существует потребность накапливать строку со временем (как прогоны программы) или пространство (составленный из значений, прибывающих из различных частей кода), способом который невозможно записать как однострочное выражение, затем StringBuilder избегает издержек (время и взбалтывание памяти):
String s = somethingExpression;
...
s += someOtherExpression;
...
s += yetAnotherExpression;
...
Иногда на это стоит посмотреть документация :
выполнение операции конкатенации для объекта Строки или StringBuilder зависит от того, как часто выделение памяти происходит. Операция Конкатенации строк всегда выделяет память, тогда как операция конкатенации StringBuilder только выделяет память, если буфер объекта StringBuilder является слишком маленьким для размещения новых данных. Следовательно, Строковый класс предпочтителен для операции конкатенации, если постоянное число Строковых объектов связывается. В этом случае отдельные операции конкатенации могли бы даже быть объединены в единственную операцию компилятором. Объект StringBuilder предпочтителен для операции конкатенации, если произвольное число строк связывается; например, если цикл связывает случайное число строк ввода данных пользователем.
В Вашем примере, существует только единственная конкатенация на выходную строку, таким образом, StringBuilder получает Вас ничто. Необходимо использовать StringBuilder в случаях, где Вы добавляете к та же строка много раз, например:
stringOut = ...
for(...)
stringOut += "."
stringOut += string2
От Dot Net Perls :
, Когда использовать StringBuilder?
StringBuilder является полностью оптимизацией, и он не предлагает логических улучшений для строкового представления Concat кроме его внутренней реализации. Тем не менее очень важно использовать его правильно в Ваших высокоэффективных приложениях и веб-сайтах.
Иногда, это должно хорошо использовать маленькие циклы 4 или меньшего количества повторений с простой строкой Concats. Однако в пограничных случаях это может иметь катастрофические последствия. Запланируйте свои пограничные случаи с StringBuilder.
От MSDN:
[T] он Строковый класс предпочтителен для операции конкатенации, если постоянное число Строковых объектов связывается. В этом случае отдельные операции конкатенации могли бы даже быть объединены в единственную операцию компилятором. Объект StringBuilder предпочтителен для операции конкатенации, если произвольное число строк связывается; например, если цикл связывает случайное число строк ввода данных пользователем.
я предполагаю, что ответ, "он зависит" - если Вы конкатенируете в цикле больше чем с горсткой повторений затем, то StringBuilder будет почти всегда обеспечивать лучшую производительность, но единственный способ знать наверняка состоит в том, чтобы на самом деле представить.