Вопрос

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

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

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

Это было полезно?

Решение

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

Он рассматривает простую конкатенацию против StringBuilder и другие методы.

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

Другие советы

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

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

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

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

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

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

Для структуры, подобной

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

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

В конце статьи кратко излагаются эти эмпирические правила :

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

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

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

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

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

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

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

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

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

Не совсем ... вам следует использовать StringBuilder, если вы конкатенируете большие строки или у вас много конкатенаций, как в цикле.

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

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

Перефразировать

  

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

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

  • Если вы объединяете строки в цикле, вам следует рассмотреть возможность использования StringBuilder вместо обычной строки
  • В случае, если это одиночная конкатенация, вы можете вообще не увидеть разницы во времени выполнения

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

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 мс

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

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

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

Пока вы можете физически набирать количество конкатенаций (a + b + c ...), это не должно иметь большого значения. N в квадрате (при N = 10) - это 100-кратное замедление, которое не должно быть слишком плохим.

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

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

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

Одна конкатенация не стоит использовать StringBuilder. Я, как правило, использовал 5 конкатенаций.

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top