Кто-то сказал мне, что быстрее конкатенировать строки с помощью StringBuilder. Я изменил свой код, но я не вижу никаких свойств или методов для получения окончательной строки сборки.
Как я могу получить строку?
Кто-то сказал мне, что быстрее конкатенировать строки с помощью StringBuilder. Я изменил свой код, но я не вижу никаких свойств или методов для получения окончательной строки сборки.
Как я могу получить строку?
Вы можете использовать .ToString()
, чтобы получить String
из StringBuilder
.
Когда вы говорите "быстрее конкатенировать String со строковым построителем", это верно, только если вы повторно (повторяю - повторно), конкатенируя с тем же объект.
Если вы просто конкатенируете 2 строки и что-то делаете с результатом сразу как string
, нет смысла использовать StringBuilder
.
Я просто наткнулся на Джона Скита, напишу об этом: http://www.yoda.arachsys.com/csharp/stringbuilder.html
Если вы используете StringBuilder
, то для получения результирующего string
это просто вызов ToString()
(неудивительно).
Как только вы завершили обработку с помощью StringBuilder, используйте метод ToString, чтобы вернуть окончательный результат.
Из MSDN:
using System;
using System.Text;
public sealed class App
{
static void Main()
{
// Create a StringBuilder that expects to hold 50 characters.
// Initialize the StringBuilder with "ABC".
StringBuilder sb = new StringBuilder("ABC", 50);
// Append three characters (D, E, and F) to the end of the StringBuilder.
sb.Append(new char[] { 'D', 'E', 'F' });
// Append a format string to the end of the StringBuilder.
sb.AppendFormat("GHI{0}{1}", 'J', 'k');
// Display the number of characters in the StringBuilder and its string.
Console.WriteLine("{0} chars: {1}", sb.Length, sb.ToString());
// Insert a string at the beginning of the StringBuilder.
sb.Insert(0, "Alphabet: ");
// Replace all lowercase k with uppercase K's.
sb.Replace('k', 'K');
// Display the number of characters in the StringBuilder and its string.
Console.WriteLine("{0} chars: {1}", sb.Length, sb.ToString());
}
}
// This code produces the following output.
//
// 11 chars: ABCDEFGHIJk
// 21 chars: Alphabet: ABCDEFGHIJK
Я бы просто хотел выбросить, что может не обязательно быстрее, у него, безусловно, будет больше памяти. Это связано с тем, что строка неизменна в .NET и каждый раз, когда вы меняете строку, вы создали новую.
Это не быстрее concat. Как указывал smaclell, проблема заключается в неизменной строке, которая требует дополнительного выделения и повторения существующих данных.
"a" + "b" + "c" не работает быстрее с построителем строк, но повторные конкаты с промежуточной строкой становятся все быстрее и быстрее по мере того, как число concat больше:
x = "a"; х + = "б"; х + = "C";...
Об этом быстрая/лучшая память:
Я рассмотрел эту проблему с Java, я полагаю, что .NET будет таким же умным.
Реализация для String довольно впечатляет.
Объект String отслеживает "длину" и "общий" (независимо от длины массива, который содержит строку)
Так что-то вроде
String a = "abc" + "def" + "ghi";
может быть реализован (компилятором/временем выполнения) как:
- Extend the array holding "abc" by 6 additional spaces. - Copy def in right after abc - copy ghi in after def. - give a pointer to the "abc" string to a - leave abc length at 3, set a length to 9 - set the shared flag in both.
Поскольку большинство строк недолговечны, во многих случаях это делает некоторый ОЧЕНЬ эффективный код. Случай, когда он абсолютно НЕ эффективен, когда вы добавляете строку в цикле или когда ваш код выглядит следующим образом:
a = "abc";
a = a + "def";
a += "ghi";
В этом случае вам гораздо лучше использовать конструкцию StringBuilder.
Моя точка зрения заключается в том, что вы должны быть осторожны при оптимизации, если только вы НЕ ДОПУСКАЕТЕ, что знаете, что делаете, И вы абсолютно уверены, что это необходимо. И вы проверяете, чтобы оптимизированный код делал проход, просто скопируйте его самым читаемым способом и не пытайтесь выдумать компилятор.
Я потратил 3 дня на использование строк, кеширование/повторное использование строковых сборщиков и скорость тестирования, прежде чем я посмотрел на исходный код строки и понял, что компилятор уже делал это лучше, чем я мог, для моего варианта использования. Затем я должен был объяснить, как я НЕ ДЕЙСТВИТЕЛЬНО знал, что делаю, я думал, что сделал...