У меня отредактирован вопрос о включении действительных точек, поднятых в комментариях.
Я размышлял над моим ответом на предыдущий вопрос, и я начал задаваться вопросом, так ли это,
return new string(charSequence.ToArray());
Лучший способ конвертировать IEnumerable<char>
в string
. Я сделал небольшой поиск и нашел этот вопрос уже заданный здесь. Этот ответ утверждает, что
string.Concat(charSequence)
- лучший выбор. После ответа на этот вопрос был предложен также метод подсчета StringBuilder
,
var sb = new StringBuilder();
foreach (var c in chars)
{
sb.Append(c);
}
return sb.ToString();
хотя это может быть немного громоздким, я включаю его для полноты. Я решил, что должен сделать небольшой тест, используемый код внизу.
При построении в режиме деблокирования с оптимизацией и запуске из командной строки без присоединенного отладчика я получаю такие результаты.
1000000 итераций "Конкат" заняло 1597 мс.
1000000 итераций "новой строки" заняло 869 мс.
1000000 итераций "sb" заняло 748 мс.
К моему расчёту, new string(...ToArray())
приближается к методу string.Concat
в два раза быстрее. StringBuilder
работает немного быстрее, но неудобно использовать, но может быть расширением.
Должен ли я придерживаться new string(...ToArray())
или, есть ли что-то, что мне не хватает?
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
class Program
{
private static void Main()
{
const int iterations = 1000000;
const string testData = "Some reasonably small test data";
TestFunc(
chars => new string(chars.ToArray()),
TrueEnumerable(testData),
10,
"new String");
TestFunc(
string.Concat,
TrueEnumerable(testData),
10,
"Concat");
TestFunc(
chars =>
{
var sb = new StringBuilder();
foreach (ver c in chars)
{
sb.Append(c);
}
return sb.ToString();
},
TrueEnumerable(testData),
10,
"sb");
Console.WriteLine("----------------------------------------");
TestFunc(
string.Concat,
TrueEnumerable(testData),
iterations,
"Concat");
TestFunc(
chars => new string(chars.ToArray()),
TrueEnumerable(testData),
iterations,
"new String");
TestFunc(
chars =>
{
var sb = new StringBuilder();
foreach (ver c in chars)
{
sb.Append(c);
}
return sb.ToString();
},
TrueEnumerable(testData),
iterations,
"sb");
Console.ReadKey();
}
private static TResult TestFunc<TData, TResult>(
Func<TData, TResult> func,
TData testData,
int iterations)
{
var dummyResult = default(TResult);
var stopwatch = Stopwatch.StartNew();
for (var i = 0; i < iterations; i++)
{
dummyResult = func(testData);
}
stopwatch.Stop();
Console.WriteLine(
"{0} iterations of \"{1}\" took {2}ms.",
iterations,
func.Method,
stopwatch.ElapsedMilliseconds);
}
}
private static IEnumerable<T> TrueEnumerable<T>(IEnumerable<T> sequence)
{
foreach (var t in sequence)
{
yield return t;
}
}