casperOne абсолютно точно зависит от данных . Однако предположим, что вы пишете это как библиотеку классов для использования третьими лицами - что бы вы использовали?
Один из вариантов - получить лучшее из обоих миров - определить, сколько данных вам действительно нужно добавить, а затем использовать StringBuilder.EnsureCapacity , чтобы убедиться, что нам нужен только один изменение размера буфера.
Если бы меня не беспокоили слишком , я бы использовал Append
x3 - кажется, "более вероятно" будет быстрее, так как разбор токенов формата строки при каждом вызове явно делает работа.
Обратите внимание, что я попросил команду BCL создать своего рода "кэшированный форматер", который мы могли бы создать с использованием строки формата, а затем повторно использовать повторно. Это безумие, что фреймворк должен анализировать строку формата каждый раз, когда он используется.
РЕДАКТИРОВАТЬ: Хорошо, я немного отредактировал код Джона для гибкости и добавил «AppendWithCapacity», который сначала просто определяет необходимую емкость. Вот результаты для разных длин - для длины 1 я использовал 1 000 000 итераций; для всех других длин я использовал 100 000. (Это было только для того, чтобы получить разумное время выполнения.) Время указано в миллис.
К сожалению, таблицы на самом деле не работают в SO. Длина была 1, 1000, 10000, 20000
Times:
- Приложение: 162, 475, 7997, 17970
- AppendFormat: 392, 499, 8541, 18993
- AppendWithCapacity: 139, 189, 1558, 3085
Так что, как это случилось, я никогда не видел ритм AppendFormat beat, но я сделал См. Победа AppendWithCapacity с очень существенным отрывом.
Вот полный код:
using System;
using System.Diagnostics;
using System.Text;
public class StringBuilderTest
{
static void Append(string string1, string string2)
{
StringBuilder sb = new StringBuilder();
sb.Append(string1);
sb.Append("----");
sb.Append(string2);
}
static void AppendWithCapacity(string string1, string string2)
{
int capacity = string1.Length + string2.Length + 4;
StringBuilder sb = new StringBuilder(capacity);
sb.Append(string1);
sb.Append("----");
sb.Append(string2);
}
static void AppendFormat(string string1, string string2)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}----{1}", string1, string2);
}
static void Main(string[] args)
{
int size = int.Parse(args[0]);
int iterations = int.Parse(args[1]);
string method = args[2];
Action<string,string> action;
switch (method)
{
case "Append": action = Append; break;
case "AppendWithCapacity": action = AppendWithCapacity; break;
case "AppendFormat": action = AppendFormat; break;
default: throw new ArgumentException();
}
string string1 = new string('x', size);
string string2 = new string('y', size);
// Make sure it's JITted
action(string1, string2);
GC.Collect();
Stopwatch sw = Stopwatch.StartNew();
for (int i=0; i < iterations; i++)
{
action(string1, string2);
}
sw.Stop();
Console.WriteLine("Time: {0}ms", (int) sw.ElapsedMilliseconds);
}
}