【发布时间】:2018-11-06 21:33:41
【问题描述】:
如果我已经只有 ReadOnlySpan 切片,连接字符串的最有效方法是什么?
简化示例:
public class Program {
public string ConcatSpans(string longstring) {
var span = longstring.AsSpan();
var sb = new StringBuilder(longstring.Length);
sb.Append(span.Slice(40, 10));
sb.Append(span.Slice(30, 10));
sb.Append(span.Slice(20, 10));
sb.Append(span.Slice(10, 10));
sb.Append(span.Slice(0, 10));
return sb.ToString();
}
[Benchmark]
public void ConcatSpansBenchmark() {
ConcatSpans("aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeee");
}
public static void Main(string[] args) {
var summary = BenchmarkRunner.Run<Program>();
}
}
结果:
BenchmarkDotNet=v0.11.2, OS=Windows 10.0.17134.345 (1803/April2018Update/Redstone4)
Intel Core i5-2500K CPU 3.30GHz (Sandy Bridge), 1 CPU, 4 logical and 4 physical cores
.NET Core SDK=2.1.403
[Host] : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT
DefaultJob : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT
Method | Mean | Error | StdDev | Gen 0/1k Op | Gen 1/1k Op | Gen 2/1k Op | Allocated Memory/Op |
--------------------- |---------:|---------:|---------:|------------:|------------:|------------:|--------------------:|
ConcatSpansBenchmark | 126.6 ns | 1.712 ns | 1.601 ns | 0.0966 | - | - | 304 B |
StringBuilder 真的是我们能做的最好的吗?有没有比这更快的方法?分配更少?毕竟StringBuilder对象本身就是一个堆对象。
如果有一个ref struct StringBuilder 只会保留对ReadOnlySpans 的引用,而在最终的ToString 中只分配一个字符串对象?
【问题讨论】:
-
好吧,我没有硬性要求。这更像是一个实验。试图找到“简单而有效”的最佳点:)。当然,分配一个缓冲区,在那里复制切片听起来是最有效的方法,但如果不知道长度就会变得更加困难(我知道在我的示例中,但只是假设)。
-
顺便说一句:感谢您使用 BenchmarkDotNet 开始一个性能问题 - 使用起来更容易!
标签: .net performance .net-core stringbuilder