针对 .Net Core 2.1 的发布进行了编辑
重复测试.Net Core 2.1的发布,我得到这样的结果
“Concat”的 1000000 次迭代耗时 842 毫秒。
“新字符串”的 1000000 次迭代耗时 1009 毫秒。
“sb”的 1000000 次迭代耗时 902 毫秒。
简而言之,如果您使用的是 .Net Core 2.1 或更高版本,Concat
则为王。
我已经编辑了这个问题,以纳入评论中提出的有效观点。
我正在思考我对上一个问题的回答,我开始怀疑,这是,
return new string(charSequence.ToArray());
将 a转换IEnumerable<char>
为string
. 我做了一点搜索,发现这个问题已经在这里问过了。该答案断言,
string.Concat(charSequence)
是更好的选择。在回答了这个问题之后,StringBuilder
还建议了一种枚举方法,
var sb = new StringBuilder();
foreach (var c in chars)
{
sb.Append(c);
}
return sb.ToString();
虽然这可能有点笨拙,但为了完整起见,我将其包括在内。我决定我应该做一个小测试,使用的代码在底部。
当在发布模式下进行优化,并在没有附加调试器的情况下从命令行运行时,我会得到这样的结果。
“Concat”的 1000000 次迭代耗时 1597 毫秒。
“新字符串”的 1000000 次迭代耗时 869 毫秒。
“sb”的 1000000 次迭代耗时 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 (var 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 (var 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,
string stage)
{
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 \"{2}\" took {1}ms.",
iterations,
stopwatch.ElapsedMilliseconds,
stage);
return dummyResult;
}
private static IEnumerable<T> TrueEnumerable<T>(IEnumerable<T> sequence)
{
foreach (var t in sequence)
{
yield return t;
}
}
}