На данный вопрос уже ответили:
Быстродействие объединения строк
1 ответ
Update: Мои тесты были неправильные. StringBuilder выигрывает даже при объединении 5 строк
Я сравнил производительность StringBuilder и String.Concat c разным количеством строк, учитывая время на создание объекта StringBuilder.
При объединении 5 строк String.Concat всегда быстрее, иногда в 10 раз
При объедении 10 строк String.Concat всегда быстрее, иногда в 10 раз
При объединении 20 строк String.Concat всегда быстрее, иногда в 10 раз
Если ли смысл использовать StringBuilder для объединения маленького количества строк? Вроде объект StringBuilder сам по себе отнимает больше ресурсов, чем 20 строк.
Код, который использовался для теста:
class Program
{
static void Main(string[] args)
{
const int countOfStrings = 20;
string[] stringsToMerge = new string[countOfStrings];
for (int i = 0; i < countOfStrings; i++)
{
stringsToMerge[i] = "stringN" + i;
}
Console.WriteLine("Count of strings:" + countOfStrings);
Stopwatch stopWatch = new Stopwatch();
TimeSpan ts;
stopWatch.Start();
stopWatch.Stop();
stopWatch.Restart();
string s = stringsToMerge[0];
for (int i = 1; i < countOfStrings; i++)
{
s = string.Concat(s, stringsToMerge[i]);
}
stopWatch.Stop();
ts = stopWatch.Elapsed;
Console.WriteLine("String.Concat ms:" + ts.TotalMilliseconds);
stopWatch.Restart();
StringBuilder stringBuilder = new StringBuilder(stringsToMerge[0]);
for (int i = 1; i < countOfStrings; i++)
{
stringBuilder.Append(stringsToMerge[i]);
}
stopWatch.Stop();
ts = stopWatch.Elapsed;
Console.WriteLine("StringBuilder ms:" + ts.TotalMilliseconds);
Console.ReadKey();
}
}
Ответ
Я исправил ваш код. Во-первых, перед тестированием скорости, все методы нужно "прогреть". При первом вызове JIT-компилятор генерирует машинный код с IL и это занимает некоторое время. Во-вторых, не нужно тестировать одну итерацию, так как случайное событие в ОС может исказить результат. Во-третьих, вы передаете странное значение, в конструктор StringBuilder. При его использовании заведомо создается маленький размер буфера, который будет расширяться несколько раз. Для максимальной производительности, если есть возможность, вы должны задавать размер буфера, который не будет менятся.
И не забывайте запускать в Release, а не в Debug
В исправленном варианте (не трогал конструктор):
Count of strings:5
String.Concat ms:1097.4772
StringBuilder ms:1294.881
Count of strings:10
String.Concat ms:2848.4845
StringBuilder ms:1970.4477
Уже на 10 выигрывает StringBuilder
const int countOfStrings = 5;
const int iterations = 10000000;
string[] stringsToMerge = new string[countOfStrings];
for (int i = 0; i < countOfStrings; i++)
{
stringsToMerge[i] = "stringN" + i;
}
// компилируем IL в машинный код
string.Concat("123", "qwe");
var x = new StringBuilder(40);
x.Append("123qwe");
Console.WriteLine("Count of strings:" + countOfStrings);
Stopwatch stopWatch = new Stopwatch();
TimeSpan ts;
stopWatch.Start();
stopWatch.Stop();
stopWatch.Restart();
for (int iter = 0; iter < iterations; iter++)
{
string s = stringsToMerge[0];
for (int i = 1; i < countOfStrings; i++)
{
s = string.Concat(s, stringsToMerge[i]);
}
}
stopWatch.Stop();
ts = stopWatch.Elapsed;
Console.WriteLine("String.Concat ms:" + ts.TotalMilliseconds);
stopWatch.Restart();
for (int iter = 0; iter < iterations; iter++)
{
StringBuilder stringBuilder = new StringBuilder(stringsToMerge[0]);
for (int i = 1; i < countOfStrings; i++)
{
stringBuilder.Append(stringsToMerge[i]);
}
}
stopWatch.Stop();
ts = stopWatch.Elapsed;
Console.WriteLine("StringBuilder ms:" + ts.TotalMilliseconds);
Если же я переделаю использование StringBuilder, то он выигрывает уже на 5 строках:
StringBuilder stringBuilder = new StringBuilder(100);
for (int i = 0; i < countOfStrings; i++)
{
stringBuilder.Append(stringsToMerge[i]);
}
Count of strings:5
String.Concat ms:1053.0082
StringBuilder ms:699.7725
Комментариев нет:
Отправить комментарий