Fügen wir einen weiteren hinzu!
Vor kurzem hat Microsoft ein spezielles NuGet-Paket veröffentlicht, System.Runtime.CompilerServices.Unsafe . Es ist etwas Besonderes, weil es in IL und bietet Low-Level-Funktionen, die in C# nicht direkt verfügbar sind.
Eine ihrer Methoden, Unsafe.As<T>(object)
ermöglicht das Casting eines beliebigen Referenztyps in einen anderen Referenztyp, wobei alle Sicherheitsüberprüfungen übersprungen werden. Dies ist normalerweise ein sehr eine schlechte Idee, aber wenn beide Typen die gleiche Struktur haben, kann es funktionieren. Wir können dies also verwenden, um eine byte[]
zu einer long[]
:
bool CompareWithUnsafeLibrary(byte[] a1, byte[] a2)
{
if (a1.Length != a2.Length) return false;
var longSize = (int)Math.Floor(a1.Length / 8.0);
var long1 = Unsafe.As<long[]>(a1);
var long2 = Unsafe.As<long[]>(a2);
for (var i = 0; i < longSize; i++)
{
if (long1[i] != long2[i]) return false;
}
for (var i = longSize * 8; i < a1.Length; i++)
{
if (a1[i] != a2[i]) return false;
}
return true;
}
なお long1.Length
würde immer noch die ursprüngliche Länge des Arrays zurückgeben, da sie in einem Feld in der Speicherstruktur des Arrays gespeichert ist.
Diese Methode ist nicht ganz so schnell wie die anderen hier vorgestellten Methoden, aber sie ist viel schneller als die naive Methode, verwendet keinen unsicheren Code oder P/Invoke oder Pinning, und die Implementierung ist recht einfach (IMO). Hier sind einige BenchmarkDotNet Ergebnisse von meinem Rechner:
BenchmarkDotNet=v0.10.3.0, OS=Microsoft Windows NT 6.2.9200.0
Processor=Intel(R) Core(TM) i7-4870HQ CPU 2.50GHz, ProcessorCount=8
Frequency=2435775 Hz, Resolution=410.5470 ns, Timer=TSC
[Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1637.0
DefaultJob : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1637.0
Method | Mean | StdDev |
----------------------- |-------------- |---------- |
UnsafeLibrary | 125.8229 ns | 0.3588 ns |
UnsafeCompare | 89.9036 ns | 0.8243 ns |
JSharpEquals | 1,432.1717 ns | 1.3161 ns |
EqualBytesLongUnrolled | 43.7863 ns | 0.8923 ns |
NewMemCmp | 65.4108 ns | 0.2202 ns |
ArraysEqual | 910.8372 ns | 2.6082 ns |
PInvokeMemcmp | 52.7201 ns | 0.1105 ns |
Ich habe auch eine gist mit allen Tests .