Я получаю приблизительно 5 сообщений в секунду. У каждого из них есть строка, которую я связываю к основной строке, которая содержит все полученные сообщения
string _masterText = "";
public void AddNewMessage(string text) // this is going to be call at least 5 times/second
{
_masterText += text;
}
Действительно ли это - appropiated способ сделать это? или если я использую вместо этого StringBuilder, как:
StringBuilder _masterText = new StringBuilder();
public void AddNewMessage(string text) // this is going to be call at least 5 times/second
{
_masterText.Append(text);
}
Спасибо
StringBuilder обычно считается лучшим вариантом, но в данном случае я бы использовал ни то, ни другое.
Даже если использовать StringBuilder, то при такой скорости буфер символов, лежащий в основе, скоро сам станет достаточно большим, чтобы застрять в Large Object Heap. Это создаст проблемы для здоровья приложения, которое должно работать в течение некоторого времени.
Вместо этого я бы использовал System.Collections.Generic.List
и просто вызывал его метод .Add()
для каждого нового сообщения. В зависимости от того, что вы делаете с этими сообщениями, вы также можете найти другой тип коллекции, более подходящий (возможно, Queue
), но вам следует двигаться именно в этом направлении. При использовании коллекции память, используемая каждой отдельной строкой, не будет учитываться в размере объекта коллекции. Вместо этого каждая строка будет добавлять только несколько байт для ссылки. В этом случае проблемы с уплотнением большой кучи объектов будут возникать гораздо дольше.
Если после перехода на коллекцию у вас все еще возникают проблемы, вы можете использовать stream и записывать строки на диск. Таким образом, у вас никогда не будет более одной строки в оперативной памяти одновременно. Теперь проблемы могут возникнуть только в том случае, если размер отдельных строк составляет 85000 байт или больше.
Помните, что класс String
неизменяем. Невозможно изменить строку. Когда вы «объединяете» строки, вы действительно создаете новую строку и копируете в нее содержимое исходной строки, а затем добавляете содержимое вашей новой строки.
Это начинает очень быстро использовать память, если вы добавляете большие строки.
Если вы готовы прочитать, я думаю, обсуждение на http://dotnetperls.com/stringbuilder-1 действительно полезно. Ознакомьтесь с ссылками на реальные показатели скорости и использования памяти.
Также ознакомьтесь с обсуждением Джоэлом Спольски « Алгоритма Шлемейла-художника ». Хотя он говорит о функции C strcat
, этот принцип применим к оператору C # плюс для строк. Кроме того, это хорошо для смеха.
В общем, я рекомендую StringBuilder, если вы выполняете операцию добавления быстро или с большим количеством больших строк.
Это также зависит от сценария. Несомненно, это быстрее добавить с помощью универсального списка по сравнению с объектом построителя строк. Но во время извлечения данных из общего списка он будет намного медленнее по сравнению с объектом построителя строк.
Построитель строк быстро вернется с помощью _masterText.ToString (), но с общим списком вам, возможно, придется извлечь значение, используя итерацию. И это будет дорогостоящий процесс, такой как: -
for (int x = 0; x < 100; x++)
{
Label3.Text += gen_list[x];
}
Или вы можете попробовать с
Label3.Text = string.Join ("", gen_list.ToArray ());
, тогда операция поиска будет медленнее и дорого, и вы можете легко заметить скачок производительности процессора.
Каждые 200 мсек - это не очень утомительный опрос, независимо от того, что построитель строк всегда лучше.