How can I do this fast?
Sure I can do this:
static bool ByteArrayCompare(byte[] a1, byte[] a2)
{
if (a1.Length != a2.Length)
return false;
for (int i=0; i<a1.Length; i++)
if (a1[i]!=a2[i])
return false;
return true;
}
But I'm looking for either a BCL function or some highly optimized proven way to do this.
java.util.Arrays.equals((sbyte[])(Array)a1, (sbyte[])(Array)a2);
works nicely, but it doesn't look like that would work for x64.
Note my super-fast answer here.
The short answer is this:
In such a way you can use the optimized .NET string compare to make a byte array compare without the need to write unsafe code. This is how it is done in the background:
Since many of the fancy solutions above don't work with UWP and because I love Linq and functional approaches I pressent you my version to this problem. To escape the comparison when the first difference occures, I chose .FirstOrDefault()
I would use unsafe code and run the
for
loop comparing Int32 pointers.Maybe you should also consider checking the arrays to be non-null.
.NET 3.5 and newer have a new public type,
System.Data.Linq.Binary
that encapsulatesbyte[]
. It implementsIEquatable<Binary>
that (in effect) compares two byte arrays. Note thatSystem.Data.Linq.Binary
also has implicit conversion operator frombyte[]
.MSDN documentation:System.Data.Linq.Binary
Reflector decompile of the Equals method:
Interesting twist is that they only proceed to byte-by-byte comparison loop if hashes of the two Binary objects are the same. This, however, comes at the cost of computing the hash in constructor of
Binary
objects (by traversing the array withfor
loop :-) ).The above implementation means that in the worst case you may have to traverse the arrays three times: first to compute hash of array1, then to compute hash of array2 and finally (because this is the worst case scenario, lengths and hashes equal) to compare bytes in array1 with bytes in array 2.
Overall, even though
System.Data.Linq.Binary
is built into BCL, I don't think it is the fastest way to compare two byte arrays :-|.Kind of brute force, but its straightforward to convert a byte array to a Base64 string and compare the two strings. Handy if you've got big arrays to compare. Or if one of the byte arrays are already in Base64 format.
I imagine that the fastest way (with the best performance for large arrays) is to hash both byte arrays and compare the hashes.
I developed a method that slightly beats
memcmp()
(plinth's answer) and very slighly beatsEqualBytesLongUnrolled()
(Arek Bulski's answer). Basically, it unrolls the loop by 4 instead of 8.This runs about 25% faster than
memcmp()
and about 5% faster thanEqualBytesLongUnrolled()
on my machine.