Как правильно использовать StringBuilder
Я немного запутался в использовании classа StringBuilder
, сначала:
Операция конкатенации
string
объекта всегда создает новый объект из существующейstring
и новых данных. ОбъектStringBuilder
поддерживает буфер для размещения конкатенации новых данных. Новые данные добавляются в конец буфера, если комната доступна; в противном случае выделяется новый, более крупный буфер, данные из исходного буфера копируются в новый буфер, а затем новые данные добавляются в новый буфер.
Но где смысл создания экземпляра StringBuilder
чтобы избежать создания новой String
? Это звучит как торговля «один на один».
- Разница между строкой и StringBuilder в c #
- Разница между StringBuilder и StringBuffer
- Правильный способ использования StringBuilder в SQL
- Емкость StringBuilder ()
- StringBuilder vs Конкатенация строк в toString () в Java
static void Main(string[] args) { String foo = "123"; using (StringBuilder sb = new StringBuilder(foo)) // also sb isn't disposable, so there will be error { sb.Append("456"); foo = sb.ToString(); } Console.WriteLine(foo); Console.ReadKey(); }
Почему я не должен просто использовать
+=
Изменить: Хорошо, теперь я знаю, как повторно использовать один экземпляр StringBuilder
(до сих пор не знаю, правильно ли это относится к стандартам кода), но это не стоит использовать только с одной string
, не так ли?
- Удалить последний символ StringBuilder?
- Является ли String.Format таким же эффективным, как StringBuilder
- Когда использовать StringBuilder?
- Как очистить или удалить StringBuilder?
- Java: String concat vs StringBuilder - оптимизирован, и что мне делать?
- В чем разница между String и StringBuffer в Java?
- Как удалить пустые строки из форматированной строки?
- интересное OutOfMemoryException с StringBuilder
Изменение неизменяемых структур, таких как string
s, должно выполняться путем копирования структуры и тем самым потреблять больше памяти и замедлять время выполнения приложения (также увеличивая время GC
и т. Д.).
StringBuilder
приходит к решению этой проблемы, используя один и тот же изменяемый объект для манипуляций.
Однако:
при конкатенации string
во время компиляции следующим образом:
string myString = "123"; myString += "234"; myString += "345";
он действительно скомпилирует что-то вроде этого:
string myString = string.Concat("123", "234", "345");
эта функция работает быстрее, чем работа с StringBuilder
для того, чтобы количество string
входящих в функцию, было известно.
поэтому для компиляции с известными string
конкатенациями вы должны предпочесть string.Concat()
.
как и для неизвестного числа string
например, в следующем случае:
string myString = "123"; if (Console.ReadLine() == "a") { myString += "234"; } myString += "345";
Теперь компилятор не может использовать string.Concat()
, однако StringBuilder
, по-видимому, более эффективен во времени и потреблении памяти только тогда, когда конкатенация выполняется с 6-7 или более strings
.
Плохое использование практики:
StringBuilder myString = new StringBuilder("123"); myString.Append("234"); myString.Append("345");
Использование тонкой практики (обратите внимание, что if
используется):
StringBuilder myString = new StringBuilder("123"); if (Console.ReadLine() == "a") { myString.Append("234"); } myString.Append("345");
Использование лучшей практики (обратите внимание, что в while
цикл используется):
StringBuilder myString = new StringBuilder("123"); while (Console.ReadLine() == "a") { myString.Append("234"); //Average loop times 4~ or more } myString.Append("345");
string
– неизменный class . Вы не можете его изменить, только создайте новые strings
.
Поэтому, когда вы пишете result += a;
в этой точке у вас есть три отдельные strings
: a
, старое значение result
и новое значение. Конечно, это абсолютно нормально, если вы только конкатенируете ограниченное количество strings
. Если вы делаете это в цикле for
итерации по большой коллекции, это может стать проблемой.
Класс StringBuilder
обеспечивает повышенную производительность в этих случаях. Вместо того, чтобы создавать новые strings
для хранения результата конкатенации, он использует один и тот же объект. Поэтому, если вы используете stringBuilder.Append(a);
у вас никогда не будет эквивалента «старого значения result
».
Разумеется, эффективность этой памяти идет с ценой. Когда только конкатенирование небольшого числа strings
StringBuilder
часто менее эффективен в отношении скорости, поскольку у него больше накладных расходов по сравнению с неизменным classом string
.
Следует иметь в виду, что если вам нужны промежуточные строки, то StringBuilder
может стать менее эффективным, так как вызов .ToString()
на нем создает новую копию string
.
Причина в том, что strings
неизменяемы. При конкатенации string
вы создаете новую string
. Итак, когда вам нужно объединить много strings
вы создаете много objects
. Это не так дорого в плане памяти, поскольку каждая string
используется один раз. Но это дает дополнительную работу для GC
.
Однако StringBuilder
использует один и тот же object
каждый раз, но он делает это за счет простоты использования.