Я изучал вопрос, который мне был представлен: как написать функцию, которая берет строку в качестве ввода и возвращает строку с пробелами между символами. Функция должна быть написана для оптимизации производительности, когда она называется тысячами раз в секунду.
-
Я знаю, что .net имеет функцию под названием
String.Join
, к которой я могу передать символ пробела в качестве разделителя вместе с исходной строкой. -
Запрет использования
String.Join
, я могу использовать классStringBuilder
для добавления пробелов после каждого символа. -
Другой способ выполнить эту задачу - объявить массив символов с 2 * n-1 символами (вы должны добавить n-1 символов для пробелов). Массив символов может быть заполнен в цикле, а затем передан в строку
constructor
.
Я написал некоторый .net-код, который запускает каждый из этих алгоритмов один миллион раз каждый с параметром "Hello, World"
и измеряет, сколько времени требуется для его выполнения. Метод (3) намного, намного быстрее, чем (1) или (2).
Я знаю, что (3) должен быть очень быстрым, потому что он избегает создания каких-либо дополнительных ссылок на строки для сбора мусора, но мне кажется, что встроенная функция .net, такая как String.Join
, должна обеспечивать хорошую производительность. Почему использование String.Join
намного медленнее, чем выполнение работы вручную?
public static class TestClass
{
// 491 milliseconds for 1 million iterations
public static string Space1(string s)
{
return string.Join(" ", s.AsEnumerable());
}
//190 milliseconds for 1 million iterations
public static string Space2(string s)
{
if (s.Length < 2)
return s;
StringBuilder sb = new StringBuilder();
sb.Append(s[0]);
for (int i = 1; i < s.Length; i++)
{
sb.Append(' ');
sb.Append(s[i]);
}
return sb.ToString();
}
// 50 milliseconds for 1 million iterations
public static string Space3(string s)
{
if (s.Length < 2)
return s;
char[] array = new char[s.Length * 2 - 1];
array[0] = s[0];
for (int i = 1; i < s.Length; i++)
{
array[2*i-1] = ' ';
array[2*i] = s[i];
}
return new string(array);
}
Обновление: Я изменил свой проект на режим "Отпуск" и обновил мои прошедшие времена в вопросе соответственно.