Подтвердить что ты не робот

Конкатенация строк и String Builder. Представление

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

foreach (MyObject o in myList)
  result += o.ToString();

В списке НЕ должно быть более 5 элементов (хотя это может быть, но это очень, очень маргинальный случай) и обычно будет иметь от 1 до 3 элементов, что является общим для него, чтобы иметь только один или два.

Что будет больше производительности, сохраняя конкатенацию или используя StringBuilder?

StringBuilder bld = new StringBuilder()
foreach (MyObject o in myList)
  bld.Append(o.ToString());

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

Это лениво, элементы в списке не меняются после создания, поэтому id лениво создается один раз при вызове.

Как побочная заметка... Должен ли я использовать фиксированный массив вместо списка? Могу ли я получить какую-либо производительность или улучшить память, если я это сделаю? (Список используется только как IEnumerable)

Более общий вид вопроса может состоять в том, сколько строк достаточно, чтобы прекратить конкатенацию и начать строить?

Должен ли я даже проверить сценарий сценария?

if (myList.Count > 4) 
  ConcatWithStringBuilder(myList);
4b9b3361

Ответ 1

Обычный ответ заключается в том, что конкатенация строк более эффективна для от 4 до 8 строк. Это зависит от того, чей блог вы читаете.

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

Запустите этот код, чтобы просмотреть результаты:

const int sLen=30, Loops=5000;
DateTime sTime, eTime;
int i;
string sSource = new String('X', sLen);
string sDest = "";
// 
// Time string concatenation.
// 
sTime = DateTime.Now;
for(i=0;i<Loops;i++) sDest += sSource;
eTime = DateTime.Now;
Console.WriteLine("Concatenation took " + (eTime - sTime).TotalSeconds + " seconds.");
// 
// Time StringBuilder.
// 
sTime = DateTime.Now;
System.Text.StringBuilder sb = new System.Text.StringBuilder((int)(sLen * Loops * 1.1));
for(i=0;i<Loops;i++) sb.Append(sSource);
sDest = sb.ToString();
eTime = DateTime.Now;
Console.WriteLine("String Builder took " + (eTime - sTime).TotalSeconds + " seconds.");
// 
// Make the console window stay open
// so that you can see the results when running from the IDE.
// 
Console.WriteLine();
Console.Write("Press Enter to finish ... ");
Console.Read();

Ref. http://support.microsoft.com/kb/306822

Ответ 2

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

Для чего-то вроде 2-5 элементов нет смысла использовать StringBuilder (если вы не повторяете эту конкатенацию непрерывно). Более читаемый синтаксис "+ =" имеет большее значение.

Ответ 3

Более общий вид вопроса может состоять в том, сколько строк достаточно, чтобы прекратить конкатенацию и начать строить?

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

Если вы соедините их сразу (например, s = "A" + "b" + "c" + "d"), то использование StringBuilder, вероятно, никогда не будет иметь смысла.

Если вы можете точно предсказать длину, тогда даже для 3 строк StringBuilder будет быстрее.

Обычно StringBuilder быстрее, если у вас более 5 concats. Но даже тогда просто конкатенирование строк обычно имеет небольшие накладные расходы (если только он не работает в узкой петле).

Как только вы достигнете 10 concats, используя StringBuilder, вероятно, будет выгодно.

Изменить: просто для того, чтобы было ясно: в вашем случае вы должны явно идти без StringBuilder.

Ответ 4

Почему вы не можете использовать

String.Concat(myList)

вместо того, чтобы изобретать колесо? Он обладает высокой производительностью и, тем не менее, прост. Подробнее здесь: http://msdn.microsoft.com/en-us/library/system.string.concat.aspx

Ответ 5

Конкатенация строк IMO более читаема. Вы используете + и + = вместо strBldInstance.Add(), который может немного испортить код,

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

Ответ 6

Строковый строитель, скорее всего, будет немного быстрее в этом случае, но на самом деле его, вероятно, не будет достаточно, чтобы волноваться. Это будет зависеть от двух вещей: количества повторений, созданных строкой (потому что строки неизменяемы и объединяются, чтобы создать новую строку из двух существующих) и размер элементов строки, которые вы объединяются вместе. Объединение пяти строк, которые имеют по 2 байта, будет сильно отличаться от конкатенации 5 строк, каждая из которых содержит по 5000 байтов, поскольку чем длиннее строка, тем больше работы система должна делать, чтобы выделять память и мусор, собирать объекты, которые не являются более длительный срок эксплуатации. Строковый строитель - лучшая ставка, потому что он уже оптимизирован для объединения строк вместе, и вам действительно не нужно беспокоиться о соображениях производительности.

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

Ответ 7

Если вы можете оценить количество байтов, которые будут использоваться для полной строки (и использовать это для инициализации емкости StringBuilder), StringBuilder, скорее всего, превзойдет класс String при выполнении более чем 3 конкат.

Ответ 8

Я бы использовал StringBuilder только потому, что вы хотите быть последовательным во всем приложении. Игнорирование объекта Java/.NET не требует больших затрат времени, хотя я бы предположил, что при настройке для StringBuilder будет некоторая домашняя работа. Не намного хуже, чем создание нескольких объектов String с помощью конкатенации.

Ответ 9

Если вы можете, вы могли бы повеселиться и полностью отказаться от цикла for и использовать агрегат?

var concatstring = mylist.Aggregate("", (acc, item) => acc + "." + item);

не уверен, что это накладные расходы?

Ответ 10

Нашел эту (производительность) тему при решении проблемы кода leetcode. Для строки, имеющей> 42 тыс. (Или более) символов, stringBuilder по некоторым причинам быстрее.

Мой следующий код для обращения строки работал в указанном случае (> 42 тыс. Символов) с StringBuilder.

public static string ReverseString(string s)
{
   var toReturn = new StringBuilder();
   for (var i = s.Length - 1; i >= 0; i--)
   {
      toReturn.Append(s[i]);
      }
   return toReturn.ToString();
}

но та же функция не работала с конкатенацией строк, т.е. toReturn + = s [i].