Span<T>
bietet eine äußerst wettbewerbsfähige Alternative, ohne dass Sie verwirrenden und/oder nicht portierbaren Ballast in die Codebasis Ihrer eigenen Anwendung einbringen müssen:
// byte[] is implicitly convertible to ReadOnlySpan<byte>
static bool ByteArrayCompare(ReadOnlySpan<byte> a1, ReadOnlySpan<byte> a2)
{
return a1.SequenceEqual(a2);
}
Die (Grundzüge der) Implementierung ab .NET 5.0.0 finden Sie unter ici .
Ich habe überarbeitet @EliArbel's gist um diese Methode hinzuzufügen als SpansEqual
, lassen Sie die meisten uninteressanten Leistungen in anderen Benchmarks weg, führen Sie ihn mit verschiedenen Array-Größen aus, geben Sie Graphen aus und markieren Sie SpansEqual
als Ausgangsbasis, so dass sie berichtet, wie die verschiedenen Methoden im Vergleich zu SpansEqual
.
Die folgenden Zahlen stammen aus den Ergebnissen, die leicht bearbeitet wurden, um die Spalte "Fehler" zu entfernen.
| 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 |
Ich war überrascht, als ich sah SpansEqual
bei den max-array-size-Methoden nicht die Nase vorn haben, aber der Unterschied ist so gering, dass ich nicht glaube, dass es jemals eine Rolle spielen wird.
Meine Systeminformationen:
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