Вопрос по stringbuilder, c# – Когда использовать StringBuilder?

61

Я понимаю преимущества StringBuilder.

Но если я хочу объединить 2 строки, то я предполагаю, что лучше (быстрее) сделать это без StringBuilder. Это правильно?

В какой момент (количество строк) становится лучше использовать StringBuilder?

возможный дубликатstackoverflow.com/questions/529999/when-to-use-stringbuilder Jørn Schou-Rode
Много раз Boris Callens
Я полагаю, что это было рассмотрено ранее. Mark Schultheiss

Ваш Ответ

12   ответов
67

Печальная трагедия театра микрооптимизацииДжефф Этвуд.

Это рассматривает Простую Конкатенацию против StringBuilder против других методов.

Теперь, если вы хотите увидеть некоторые цифры и графики, перейдите по ссылке;)

Глупый ответ. В двух словах - "иди и прочитай это user1017882
и просто показать, насколько это важно, из статьи, на которую вы ссылаетесь: «В большинстве языков сборки мусора строки являются неизменяемыми: при добавлении двух строк содержимое обеих копируется. По мере того, как вы добавляете результат в этот цикл, каждый раз выделяется все больше и больше памяти. Это приводит к ужасной квадратической производительности n2 " Peter
Я пытался использовать stringbuilder, но проблема в том, что мне все еще нужно вызывать строку, чтобы сравнить ее со строками в другом месте кода, что, кажется, делает его более неэффективным James Joshua Street
Я могу'не совсем согласен с этой ссылкой ... ониспользуя механизм внутри метода, просто сравниваябыстрее снемного конкатенация и чтобыстрее к примеру. Если вы объявляете StringBuilder вне цикла, он явно превосходит все. Bobby
2

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

С использованиемStringBuilder Класс может повысить производительность при объединении многих строк в цикле.

Ниже приведен список нескольких операций, которые можно выполнить для манипуляции строкой с использованием класса StringBuilder в .NET.

присоединять: Добавляет информацию в конец текущего StringBuilder.

AppendFormat: Заменяет спецификатор формата, переданный в строке, форматированным текстом.

Вставить: Вставляет строку или объект в указанный индекс текущего StringBuilder.

Удалить: Удаляет указанное количество символов из текущего StringBuilder.

замещать: Заменяет указанный символ по указанному индексу.

4

то я предполагаю, чтоЛучше и быстрее сделать это без StringBuilder. Это правильно?

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

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

Будем осторожны с эмпирическими правилами, в которых в качестве порогового значения приводятся конкретные числа конкатенации ». < этот. Кроме того, после применения здравого смысла подумайте о человеке, который вернется к вашему коду через 6 месяцев. Phil Cooper
4
Если вы объединяете строки в цикле, вы должны рассмотреть возможность использования StringBuilder вместо обычной StringВ случае, если этос одной конкатенацией, вы можете вообще не увидеть разницу во времени выполнения

Вот простое тестовое приложение, чтобы доказать это:

class Program
{
    static void Main(string[] args)
    {
        const int testLength = 30000;
        var StartTime = DateTime.Now;

        //TEST 1 - String
        StartTime = DateTime.Now;
        String tString = "test string";
        for (int i = 0; i < testLength; i++)
        {
            tString += i.ToString();
        }
        Console.WriteLine((DateTime.Now - StartTime).TotalMilliseconds.ToString());
        //result: 2000 ms

        //TEST 2 - StringBuilder
        StartTime = DateTime.Now;
        StringBuilder tSB = new StringBuilder("test string");
        for (int i = 0; i < testLength; i++)
        {
            tSB.Append(i.ToString());
        }
        Console.WriteLine((DateTime.Now - StartTime).TotalMilliseconds.ToString());
        //result: 4 ms

        Console.ReadLine();
    }
}

Результаты:

30'000 итераций

Строка - 2000 мсStringBuilder - 4 мс

1000 итераций

Строка - 2 мсStringBuilder - 1 мс

500 итераций

Строка - 0 мсStringBuilder - 0 мс
4

Нет точного ответа, только эмпирические правила. Мои личные правила действуют примерно так:

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

Если это не такт, используйте.StringBuilder
Я знаю, что это старая тема, но я только знаю, обучения и хотел знать, что вы считаете "Большая строка "? MatthewD
8

если вы объединяетебольшой строки или у вас есть много конкатенаций, как в цикле.

Это не правильно. Вы должны использоватьStringBuilder только если цикл или конкатенация являются проблемой производительности для спецификаций. Alex Bagnolini
@ Конрад: Вы уверены, что естьнет выигрыш в производительности? Каждый раз, когда вы объединяете большие строки, выповторное копирование большого количества данных; Каждый раз, когда вы объединяете небольшие строки, вытолько копирование небольшого количества данных. LukeH
@Bobby: исправить, использовать литералы, а не объяснять a, b, c и буду строк :) Binary Worrier
-1 за неправильное обобщение. строка s = "a" + "b" + "c" + "d"; использует одно выделение памяти для s. Посмотрите на последнюю (9-ю) перегрузку для string.Concat. Приведенный выше код в основном компилируется в string.Concat ("a", "b", "c", "d") в MSIL. Binary Worrier
4

Тогда считай до трех, не больше и не меньше. Три должно быть числом, на которое ты считаешь, а число счета должно быть три. Четыре не считаешь, и не считаешь два, за исключением того, что ты затем переходишь к трем. Как только число три, являющееся третьим числом, будет достигнуто, тогда брось в руки твою Святую ручную гранату Антиохии

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

Это зависит: Concetanation делает только одну копию: "Рассел "+" " + Стин + ".", сделает только одну копию, потому что она заранее вычисляет длину строки. Только когда вам нужно разделить конкатенацию, вы должны начать думать о строителе Peter
38

то я предполагаю, что лучше (быстрее) сделать это без StringBuilder. Это правильно?

Это действительно правильно, вы можете найти, почему точно объяснил очень хорошо:

http://www.yoda.arachsys.com/csharp/stringbuilder.html

Подводя итог: если вы можете объединить строки за один раз, как

var result = a + " " + b  + " " + c + ..

вам лучше без StringBuilder, поскольку создается только копия (длина результирующей строки вычисляется заранее.);

Для структуры, как

var result = a;
result  += " ";
result  += b;
result  += " ";
result  += c;
..

новые объекты создаются каждый раз, поэтому вы должны рассмотреть StringBuilder.

В конце статьи суммируются следующие правила:

Эмпирические правила

Итак, когда вы должны использовать StringBuilder, и когда вы должны использовать операторы конкатенации строк?

Обязательно используйте StringBuilder, когда выповторное объединение в нетривиальном цикле - особенно если вы нене знаю наверняка (во время компиляции), сколько итераций высделаю через петлю. Например, чтение файла по символу за раз, построение строки при использовании оператора + = потенциально может привести к самоубийству из-за производительности.

Обязательно используйте оператор конкатенации, когда вы можете (читаемо) указать все, что нужно объединить в одном операторе. (Если у вас есть массив вещей для объединения, рассмотрите возможность вызова String.Concat явно - или String.Join, если вам нужен разделитель.)

Дон»не бойтесь разбивать литералы на несколько сцепленных битов - результат будет одинаковым. Вы можете улучшить читабельность, разбив длинный литерал на несколько строк, например, без ущерба для производительности.

Если вам нужны промежуточные результаты конкатенации для чего-то другого, кроме подачи следующей итерации конкатенации, StringBuilder isn 'не собираюсь тебе помогать. Например, если вы создаете полное имя из имени и фамилии, а затем добавляете третий фрагмент информации (возможно, псевдоним) в конец, вы 'Вы сможете использовать StringBuilder только в том случае, еслиСтрока (имя + фамилия) не нужна для других целей (как мы делаем в примере, который создает объект Person).

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

2

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

Для меня я не буду использовать StringBuilder, если просто объединю 2 огромные строки. Если там'S цикл с неопределенным подсчетом, яВероятно, даже если цикл может быть небольшим количеством.

На самом деле было бы совершенно неправильно использовать StringBuilder для объединения двух строк, но это не имеет ничего общего с perf. тестирование - это просто использование его для неправильной вещи. Marc Gravell
11

что всякий раз, когда вы изменяете его содержимое, он выделяет новую строку, и это занимает время (и память?). Используя StringBuilder, вы изменяете фактическое содержимое объекта без выделения нового.

Поэтому используйте StringBuilder, когда вам нужно сделать много изменений в строке.

3

.), оно не должноне имеет большого значения. N в квадрате (при N = 10) - это 100-кратное замедление, которое не должноне так уж и плохо.

Большая проблема, когда вы объединяете сотни строк. При N = 100 вы получаете замедление в 10000 раз. Что довольно плохо.

1

Как правило, мы использовали 5 конкатенаций.

Похожие вопросы