针对 .Net Core 2.1 版本进行编辑
重复测试 .Net Core 2.1 版本后,我得到了如下结果:
对 "Concat" 进行 1000000 次迭代,耗时 842ms。
对 "new String" 进行 1000000 次迭代,耗时 1009ms。
对 "sb" 进行 1000000 次迭代,耗时 902ms。
简而言之,如果您正在使用 .Net Core 2.1 或更高版本,则 Concat
是最佳选择。
我已经在问题中 编辑 了内容,以包含评论中提出的有效观点。
我正在思考 我之前回答的一个问题,并开始想知道,这是否是这样的情况:
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次“Concat”的迭代需要1597ms。 1000000次“new String”的迭代需要869ms。 1000000次“sb”的迭代需要748ms。
据我估计,`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;
}
}
}
IEnumerable
对象上进行测试(例如Enumerable.Repeat('d', 100)
),以避免构造函数/转换方法中潜在的快捷方式。 - Alexei Levenkovstring.Join("", charSequence)
。我希望它在性能方面与构造函数/字符串生成器接近。 - nawfal