StringBuilder: как получить финальную строку? - PullRequest
56 голосов
/ 23 октября 2008

Кто-то сказал мне, что быстрее объединять строки с помощью StringBuilder. Я изменил свой код, но я не вижу никаких свойств или методов, чтобы получить окончательную строку сборки.

Как мне получить строку?

Ответы [ 6 ]

108 голосов
/ 23 октября 2008

Вы можете использовать .ToString(), чтобы получить String от StringBuilder.

13 голосов
/ 23 октября 2008

Когда вы говорите «быстрее соединить String с помощью String Builder», это верно только в том случае, если вы многократно (я повторяю - многократно ) объединяются с одним и тем же объектом.

Если вы просто объединяете 2 строки и делаете что-то с результатом сразу как string, нет смысла использовать StringBuilder.

Я только что наткнулся на приятное описание Джона Скита: http://www.yoda.arachsys.com/csharp/stringbuilder.html

Если вы используете StringBuilder, то для получения результирующего string нужно просто позвонить ToString() (что неудивительно).

10 голосов
/ 23 октября 2008

После того, как вы завершили обработку с использованием 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's 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
3 голосов
/ 23 октября 2008

Я просто хотел бы выкинуть, что, возможно, не обязательно быстрее, у него определенно будет лучший след памяти. Это потому, что строка неизменна в .NET, и каждый раз, когда вы меняете строку, вы создаете новую.

2 голосов
/ 23 октября 2008

о том, что память быстрее / лучше:

Я рассмотрел эту проблему с Java, я полагаю, что .NET будет настолько же умен в этом.

Реализация для String довольно впечатляющая.

Объект String отслеживает «length» и «shared» (независимо от длины массива, в котором находится строка)

Так что-то вроде

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's length at 3, set a's length to 9
 - set the shared flag in both.

Поскольку большинство строк недолговечны, во многих случаях это дает ОЧЕНЬ эффективный код. Случай, когда он абсолютно НЕ эффективен, это когда вы добавляете строку в цикл или когда ваш код выглядит так:

a = "abc";
a = a + "def";
a += "ghi";

В этом случае вам гораздо лучше использовать конструкцию StringBuilder.

Я хочу сказать, что вы должны быть осторожны при оптимизации, если только вы не абсолютно уверены, что знаете, что делаете, И абсолютно уверены, что это необходимо, и проверяете, чтобы оптимизированный код прошел проверку, просто закодируйте его наиболее читаемым способом и не пытайтесь перехитрить компилятор.

Я потратил 3 дня на то, чтобы возиться со строками, кэшировать / повторно использовать сборщики строк и скорость тестирования, прежде чем я посмотрел на исходный код строки и обнаружил, что компилятор уже делал это лучше, чем я, возможно, мог для моего случая использования. Затем мне пришлось объяснить, как я ДЕЙСТВИТЕЛЬНО не знал, что я делаю, я только думал, что знаю ...

1 голос
/ 23 октября 2008

Конкатировать не быстрее - как указывал smaclell, проблема заключается в неизменяемой строке, требующей дополнительного выделения и повторного копирования существующих данных.

"a" + "b" + "c" не быстрее, чем при построителе строк, но повторяющиеся конкататы с промежуточной строкой становятся быстрее и быстрее, так как число конкатов увеличивается как:

x = "a"; х + = "б"; х + = "C"; ...

...