StringBuilder или + = - PullRequest
       6

StringBuilder или + =

10 голосов
/ 29 июля 2010

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

    string _masterText = "";
    public void AddNewMessage(string text)  // this is going to be call at least 5 times/second
    {
        _masterText += text;    
    }

Является ли это подходящим способом сделать это?или я должен использовать вместо StringBuilder, как:

    StringBuilder _masterText = new StringBuilder();
    public void AddNewMessage(string text) // this is going to be call at least 5 times/second
    {
         _masterText.Append(text);  
    }

Спасибо

Ответы [ 6 ]

14 голосов
/ 29 июля 2010

StringBuilder обычно считается лучшим вариантом, но в этом случае я бы не использовал ни .

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

Вместо этого я бы использовал System.Collections.Generic.List<string> и просто вызывал бы метод .Add() для каждого нового сообщения. В зависимости от того, что вы делаете с этими сообщениями, вы также можете найти другой тип коллекции более подходящим (возможно, Queue<string>), но это направление, в котором вы должны идти. При использовании коллекции память, используемая каждой отдельной строкой, не будет учитываться в размере объекта коллекции. Вместо этого каждая строка будет добавлять только несколько байтов для ссылки. Это займет гораздо больше времени, чтобы столкнуться с проблемами при сжатии кучи больших объектов.

Если после переключения на коллекцию у вас все еще есть проблемы, вы можете использовать stream и записать строки на диск. Таким образом, у вас никогда не будет более одной строки в оперативной памяти за раз. Теперь у вас могут возникнуть проблемы только в том случае, если отдельные строки имеют размер 85000 байт или более.

8 голосов
/ 29 июля 2010

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

Это начинает очень быстро использовать память, если вы добавляете большие строки.

3 голосов
/ 29 июля 2010

Каждые 200 мс - это не очень сложный опрос, независимо от того, что stringbuilder всегда лучше.

1 голос
/ 29 июля 2010

Если вы готовы к чтению, я думаю, обсуждение на http://dotnetperls.com/stringbuilder-1 действительно полезно. Проверьте ссылки на реальные показатели по скорости и использованию памяти.

Кроме того, ознакомьтесь с обсуждением Джоэла Спольски " Алгоритм художника Шлемейла ". Хотя он говорит о функции C strcat, этот принцип применяется к оператору C # плюс в строках. Кроме того, это хорошо для смеха.

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

0 голосов
/ 29 июля 2010

Это зависит и от сценария.Без сомнения, это быстрее добавить с общим списком по сравнению с объектом stringbuilder.Но во время извлечения данных из общего списка это будет намного медленнее по сравнению с объектом stringbuilder.

Строитель строк будет быстро возвращаться с помощью _masterText.ToString (), но с общим списком вы можете иметьчтобы получить значение, используя итерацию.И это будет дорогой процесс, такой как: -

  for (int x = 0; x < 100; x++)
    {
      Label3.Text += gen_list[x];
    }

Или вы можете попробовать с

Label3.Text = string.Join ("", gen_list.ToArray ());

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

0 голосов
/ 29 июля 2010

StringBuilder - ваш приятель!

...