Span<T>
提供极具竞争力的替代方案,而无需在您自己的应用程序代码库中添加令人困惑和/或不可移植的内容:
// byte[] is implicitly convertible to ReadOnlySpan<byte>
static bool ByteArrayCompare(ReadOnlySpan<byte> a1, ReadOnlySpan<byte> a2)
{
return a1.SequenceEqual(a2);
}
.NET 5.0.0 的(胆量)实现可以在这里找到。
我已经修改了@EliArbel 的要点,将这个方法添加为SpansEqual
,在其他人的基准测试中删除大多数不那么有趣的执行者,使用不同的数组大小运行它,输出图表,并标记SpansEqual
为基线,以便它报告不同方法的比较SpansEqual
.
以下数字来自结果,经过轻微编辑以删除“错误”列。
| Method | ByteCount | Mean | StdDev | Ratio | RatioSD |
|-------------- |----------- |-------------------:|------------------:|------:|--------:|
| SpansEqual | 15 | 4.629 ns | 0.0289 ns | 1.00 | 0.00 |
| LongPointers | 15 | 4.598 ns | 0.0416 ns | 0.99 | 0.01 |
| Unrolled | 15 | 18.199 ns | 0.0291 ns | 3.93 | 0.02 |
| PInvokeMemcmp | 15 | 9.872 ns | 0.0441 ns | 2.13 | 0.02 |
| | | | | | |
| SpansEqual | 1026 | 19.965 ns | 0.0880 ns | 1.00 | 0.00 |
| LongPointers | 1026 | 63.005 ns | 0.5217 ns | 3.16 | 0.04 |
| Unrolled | 1026 | 38.731 ns | 0.0166 ns | 1.94 | 0.01 |
| PInvokeMemcmp | 1026 | 40.355 ns | 0.0202 ns | 2.02 | 0.01 |
| | | | | | |
| SpansEqual | 1048585 | 43,761.339 ns | 30.8744 ns | 1.00 | 0.00 |
| LongPointers | 1048585 | 59,585.479 ns | 17.3907 ns | 1.36 | 0.00 |
| Unrolled | 1048585 | 54,646.243 ns | 35.7638 ns | 1.25 | 0.00 |
| PInvokeMemcmp | 1048585 | 55,198.289 ns | 23.9732 ns | 1.26 | 0.00 |
| | | | | | |
| SpansEqual | 2147483591 | 240,607,692.857 ns | 2,733,489.4894 ns | 1.00 | 0.00 |
| LongPointers | 2147483591 | 238,223,478.571 ns | 2,033,769.5979 ns | 0.99 | 0.02 |
| Unrolled | 2147483591 | 236,227,340.000 ns | 2,189,627.0164 ns | 0.98 | 0.00 |
| PInvokeMemcmp | 2147483591 | 238,724,660.000 ns | 3,726,140.4720 ns | 0.99 | 0.02 |
我很惊讶地看到SpansEqual
max-array-size 方法没有名列前茅,但是差异是如此之小,以至于我认为这无关紧要。
我的系统信息:
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042
Intel Core i7-6850K CPU 3.60GHz (Skylake), 1 CPU, 12 logical and 6 physical cores
.NET Core SDK=5.0.100
[Host] : .NET Core 5.0.0 (CoreCLR 5.0.20.51904, CoreFX 5.0.20.51904), X64 RyuJIT
DefaultJob : .NET Core 5.0.0 (CoreCLR 5.0.20.51904, CoreFX 5.0.20.51904), X64 RyuJIT