Да, разница в производительности значительна. См. Статью базы знаний « Как улучшить производительность конкатенации строк в Visual C # ».
Я всегда пытался сначала написать код для ясности, а потом оптимизировать для производительности. Это гораздо проще, чем сделать это наоборот! Однако, увидев огромную разницу в производительности в моих приложениях между этими двумя, я теперь думаю об этом немного более тщательно.
К счастью, сравнительно просто запустить анализ производительности вашего кода, чтобы увидеть, на что вы тратите время, а затем изменить его для использования в StringBuilder
случае необходимости.
Чтобы уточнить, что сказала Джиллиан о 4-й строке, если у вас есть что-то вроде этого:
тогда было бы быстрее использовать строки и оператор плюс. Это потому, что (как и Java, как указывает Эрик), он автоматически использует StringBuilder (на самом деле, он использует примитив, который также использует StringBuilder)
Однако, если то, что вы делаете, ближе к:
Тогда вам нужно явно использовать StringBuilder. .Net не создает автоматически StringBuilder здесь, потому что это было бы бессмысленно. В конце каждой строки «a» должна быть (неизменяемой) строкой, поэтому она должна создавать и размещать StringBuilder в каждой строке. Для скорости вам нужно будет использовать тот же StringBuilder, пока вы не закончите сборку:
источник
a
это локальная переменная, и объект, на который она ссылается, не был назначен какой-либо другой переменной (которая может быть доступна другому потоку), хороший оптимизатор может определить,a
к чему не обращается какой-либо другой код во время этой последовательности линии; только окончательная ценностьa
имеет значение. Таким образом, он может обрабатывать эти три строки кода, как если бы они были написаныa = b + c + d;
.StringBuilder предпочтительнее, если вы выполняете несколько циклов или разветвлений при передаче кода ... однако, для производительности PURE, если вы можете обойтись без объявления строк SINGLE , тогда это гораздо более производительно.
Например:
более производительный, чем
В этом случае StringBuild можно считать более поддерживаемым, но не более производительным, чем однострочное объявление.
9 раз из 10, хотя ... используйте строителя строк.
С другой стороны: строка + var также более производительна, чем подход string.Format (обычно), который использует StringBuilder для внутреннего использования (в случае сомнений ... проверьте отражатель!)
источник
Простой пример, демонстрирующий разницу в скорости при использовании
String
объединенияStringBuilder
:Результат:
Результат:
В результате первая итерация заняла 15423 мс, а вторая итерация -
StringBuilder
10 мс.Мне кажется, что использование
StringBuilder
быстрее, намного быстрее.источник
Этот тест показывает, что обычная конкатенация быстрее при объединении 3 или менее строк.
http://www.chinhdo.com/20070224/stringbuilder-is-not-always-faster/
StringBuilder может значительно улучшить использование памяти, особенно в случае добавления 500 строк вместе.
Рассмотрим следующий пример:
Что происходит в памяти? Создаются следующие строки:
Добавив эти пять чисел в конец строки, мы создали 13 строковых объектов! И 12 из них были бесполезны! Вот Это Да!
StringBuilder решает эту проблему. Это не «изменяемая строка», как мы часто слышим ( все строки в .NET являются неизменяемыми ). Работает, сохраняя внутренний буфер, массив char. Вызов Append () или AppendLine () добавляет строку в пустое пространство в конце массива char; если массив слишком мал, он создает новый, больший массив и копирует туда буфер. Таким образом, в приведенном выше примере StringBuilder может потребоваться только один массив, содержащий все 5 дополнений к строке - в зависимости от размера его буфера. Вы можете указать StringBuilder, насколько большим должен быть его буфер в конструкторе.
источник
i.ToString()
. Так что с StringBuilder вам все равно нужно создать строки 6 + 1; это уменьшило создание 13 строк до создания 7 строк. Но это все равно неправильный взгляд на это; создание шести числовых строк не имеет значения. Итог: вы просто не должны были упоминать шесть строк, созданныхi.ToString()
; они не являются частью сравнения эффективности.String Vs String Builder:
Прежде всего, вы должны знать, в каком собрании живут эти два класса?
Так,
строка присутствует в
System
пространстве имен.и
StringBuilder присутствует в
System.Text
пространстве имен.Для объявления строки :
Вы должны включить
System
пространство имен. что-то вроде этого.Using System;
и
Для объявления StringBuilder :
Вы должны включить
System.text
пространство имен. что-то вроде этого.Using System.text;
Приходите на актуальный вопрос.
В чем разница между string и StringBuilder ?
Основное различие между этими двумя заключается в том, что:
Строка неизменна.
и
StringBuilder изменчив.
Итак, теперь давайте обсудим разницу между неизменным и изменяемым
Mutable: : средства изменчива.
Неизменный: означает не изменяемый.
Например:
Так что в этом случае мы собираемся менять один и тот же объект 5 раз.
Итак, очевидный вопрос таков! Что на самом деле происходит под капотом, когда мы меняем одну и ту же струну 5 раз.
Это то, что происходит, когда мы меняем одну и ту же строку 5 раз.
давай посмотрим на фигуру.
Explaination:
Когда мы впервые инициализируем эту переменную «name» в «Rehan», то есть
string name = "Rehan"
эта переменная создается в стеке «name» и указывает на это значение «Rehan». после выполнения этой строки: "name = name +" Shah ". Переменная-ссылка больше не указывает на этот объект" Rehan ", теперь она указывает на" Shah "и так далее.То
string
же самое означает, что как только мы создаем объект в памяти, мы не можем его изменить.Поэтому, когда мы объединяем
name
переменную, предыдущий объект остается там в памяти, и создается другой новый строковый объект ...Итак, из приведенного выше рисунка у нас есть пять объектов, четыре объекта выброшены, они вообще не используются. Они все еще остаются в памяти, и они занимают объем памяти. «Сборщик мусора» отвечает за то, что так убирает ресурсы из памяти.
Так что в случае строки в любое время, когда мы манипулируем строкой снова и снова, у нас есть много объектов, созданных и находящихся там в памяти.
Так что это история строковой переменной.
Теперь давайте посмотрим на объект StringBuilder. Например:
Так что в этом случае мы собираемся менять один и тот же объект 5 раз.
Итак, очевидный вопрос таков! Что на самом деле происходит под капотом, когда мы меняем один и тот же StringBuilder 5 раз.
Вот что происходит, когда мы меняем один и тот же StringBuilder 5 раз.
давай посмотрим на фигуру.
Объяснение: В случае объекта StringBuilder . Вы не получите новый объект. Тот же объект будет изменен в памяти, поэтому даже если вы измените объект и, скажем, 10 000 раз, у нас останется только один объект stringBuilder.
У вас нет большого количества мусорных объектов или объектов non_referenced stringBuilder, потому что это может быть изменено. Это изменчивое значение, что оно меняется со временем?
Отличия:
источник
Да,
StringBuilder
дает лучшую производительность при выполнении повторной операции над строкой. Это потому, что все изменения вносятся в один экземпляр, поэтому он может сэкономить много времени вместо создания нового экземпляраString
.String Vs Stringbuilder
String
System
пространством именStringBuilder
(изменяемая строка)System.Text
пространством именисточник
StringBuilder уменьшает количество выделений и назначений за счет использования дополнительной памяти. При правильном использовании он может полностью избавить компилятор от необходимости снова и снова выделять все большие и большие строки, пока не будет найден результат.
против
источник
Источник: MSDN
источник
StringBuilder
лучше для построения строки из многих непостоянных значений.Если вы строите строку из большого количества константных значений, таких как несколько строк значений в документе HTML или XML или другие фрагменты текста, вы можете просто добавить одну и ту же строку, потому что почти все компиляторы делают «постоянное сворачивание», процесс сокращения дерева разбора, когда у вас есть куча постоянных манипуляций (это также используется, когда вы пишете что-то вроде
int minutesPerYear = 24 * 365 * 60
). А для простых случаев с непостоянными значениями, добавляемыми друг к другу, компилятор .NET уменьшит ваш код до чего-то похожего на то, чтоStringBuilder
делает.Но когда ваше добавление не может быть уменьшено компилятором до чего-то более простого, вы захотите a
StringBuilder
. Как указывает fizch, это чаще всего происходит внутри цикла.источник
Я считаю, что StringBuilder работает быстрее, если у вас есть более 4 строк, которые нужно добавить вместе. Кроме того, он может делать некоторые интересные вещи, такие как AppendLine.
источник
В .NET StringBuilder все еще быстрее, чем добавление строк. Я уверен, что в Java они просто создают StringBuffer под капотом, когда вы добавляете строки, так что на самом деле нет никакой разницы. Я не уверен, почему они еще не сделали этого в .NET.
источник
Рассмотрим « Печальную трагедию театра микрооптимизации ».
источник
Использование строк для конкатенации может привести к сложности времени выполнения порядка
O(n^2)
.Если вы используете a
StringBuilder
, то копирование памяти будет намного меньше. С помощьюStringBuilder(int capacity)
вы можете увеличить производительность, если сможете оценить, насколько большим будет финалString
. Даже если вы не точны, вам, вероятно, придется увеличить пропускную способность всегоStringBuilder
в пару раз, что также может повысить производительность.источник
Я видел значительный прирост производительности при использовании
EnsureCapacity(int capacity)
вызова метода в экземпляре,StringBuilder
прежде чем использовать его для хранения строк. Я обычно называю это в строке кода после создания экземпляра. Это имеет тот же эффект, как если бы вы создавалиStringBuilder
подобное:Этот вызов выделяет необходимую память заблаговременно, что приводит к меньшему выделению памяти во время нескольких
Append()
операций. Вы должны сделать обоснованное предположение о том, сколько памяти вам понадобится, но для большинства приложений это не должно быть слишком сложным. Я обычно ошибаюсь на стороне слишком большого количества памяти (мы говорим 1k или около того).источник
EnsureCapacity
сразу послеStringBuilder
создания экземпляра. Просто создать экземплярStringBuilder
так:var sb = new StringBuilder(int capacity)
.В дополнение к предыдущим ответам, первое, что я всегда делаю, когда думаю о таких проблемах, - это создаю небольшое тестовое приложение. Внутри этого приложения проведите некоторый временной тест для обоих сценариев и убедитесь сами, что быстрее.
ИМХО, добавление более 500 строковых записей обязательно должно использовать StringBuilder.
источник
String и StringBuilder на самом деле являются неизменными, StringBuilder имеет встроенные буферы, которые позволяют более эффективно управлять его размером. Когда StringBuilder нужно изменить размер, это когда он перераспределяется в куче. По умолчанию он имеет размер до 16 символов, вы можете установить это в конструкторе.
например.
StringBuilder sb = new StringBuilder (50);
источник
Конкатенация строк обойдется вам дороже. В Java вы можете использовать либо StringBuffer, либо StringBuilder в зависимости от ваших потребностей. Если вы хотите синхронизированную и поточно-ориентированную реализацию, выберите StringBuffer. Это будет быстрее, чем конкатенация строк.
Если вам не нужна синхронизированная или поточно-ориентированная реализация, выберите StringBuilder. Это будет быстрее, чем конкатенация строк, а также быстрее, чем StringBuffer, так как они не требуют дополнительной синхронизации.
источник
StringBuilder, вероятно, предпочтительнее. Причина в том, что он выделяет больше места, чем требуется в настоящее время (вы устанавливаете количество символов), чтобы оставить место для будущих добавлений. Тогда те будущие добавления, которые помещаются в текущий буфер, не требуют выделения памяти или сборки мусора, что может быть дорогостоящим. В общем, я использую StringBuilder для сложной конкатенации строк или многократного форматирования, затем преобразовываю в обычную строку, когда данные полны, и я снова хочу неизменный объект.
источник
Если вы делаете много конкатенации строк, используйте StringBuilder. Когда вы объединяете строку, вы каждый раз создаете новую строку, занимая больше памяти.
Alex
источник
Как общее практическое правило, если мне нужно установить значение строки более одного раза, или если есть какие-либо добавления к строке, то он должен быть строителем строки. Я видел приложения, которые я написал в прошлом, прежде чем узнал о строителях строк, у которых был огромный отпечаток памяти, который, кажется, продолжает расти и расти. Изменение этих программ для использования строителя строк значительно сокращает использование памяти. Теперь я клянусь строителем строк.
источник
Мой подход всегда заключался в использовании StringBuilder при конкатенации 4 или более строк ИЛИ когда я не знаю, как могут происходить конкатенации.
Хорошая производительность, связанная с этим статья здесь
источник
StringBuilder
значительно эффективнее, но вы не увидите эту производительность, если не будете выполнять большое количество модификаций строк.Ниже приведен небольшой фрагмент кода, чтобы привести пример производительности. Как вы можете видеть, вы действительно начинаете видеть значительное увеличение производительности, когда начинаете работать с большими итерациями.
Как вы можете видеть, 200 000 итераций заняли 22 секунды, в то время как 1 миллион итераций с использованием
StringBuilder
был почти мгновенным.Результат приведенного выше кода:
источник
StringBuilder будет работать лучше, с точки зрения памяти. Что касается обработки, то разница во времени исполнения может быть незначительной.
источник