How to compare two byte arrays ?

O

Oleg Subachev

Is there other way of comparing two byte arrays
than iterating through the two and compare individual bytes ?

Oleg Subachev
 
M

Mattias Sjögren

Is there other way of comparing two byte arrays
than iterating through the two and compare individual bytes ?

No, but you can always start by checking that their lengths are equal
first.


Mattias
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

Nop, the same goes with any kind of array or collections
 
M

Marcus Andrén

Is there other way of comparing two byte arrays
than iterating through the two and compare individual bytes ?

Oleg Subachev

In most cases it is enough to just iterate and compare each byte. In
the rare case that maximum performance is needed you could use unsafe
code to speed up the process by using int pointers.

Here is a small code snippet that demonstrates the basics. It will
only work if the array length is divisible by 4.

public unsafe static bool Compare(byte[] b1, byte[] b2)
{
fixed (byte* bp1 = b1)
{
fixed (byte* bp2 = b2)
{
int* ip1 = (int*)bp1;
int* ip2 = (int*)bp2;

for (int i = 0; i < b1.Length / 4; i++)
{
if (ip2 != ip1)
return false;
}
return true;
}
}
}
 
H

Helge Jensen

Marcus said:
Here is a small code snippet that demonstrates the basics. It will
only work if the array length is divisible by 4.

public unsafe static bool Compare(byte[] b1, byte[] b2)
{
fixed (byte* bp1 = b1)
{
fixed (byte* bp2 = b2)
{
int* ip1 = (int*)bp1;
int* ip2 = (int*)bp2;

for (int i = 0; i < b1.Length / 4; i++)

remember checking the length of b2 also, especially since this is unsafe
code. I would like the function to start with something like:

if ( b1.Length % 4 != 0 )
throw new ArgumentException("Length % 4 != 0", "b1");
if ( b2.Length % 4 != 0 )
throw new ArgumentException("Length % 4 != 0", "b2");
if ( b1.Length != b2.Length )
return false;
{
if (ip2 != ip1)
return false;
}
return true;
}
}
}


How much, and how have you measured that the above is faster, than simply

public static bool Compare(byte[] b1, byte[] b2) {
if ( b1.Length != b2.Length )
return false;
for ( int i = 0; i < b1.Length; ++i )
if ( b1 != b2 )
return false;
return true;
}
 
M

Marcus Andrén

remember checking the length of b2 also, especially since this is unsafe
code. I would like the function to start with something like:

Very true.
How much, and how have you measured that the above is faster, than simply

I had done some basic measurements earlier, but since you asked I got
a little more curious and did some more detailed testing including
what happens if the arrays doesn't match in the first few bytes of the
comparison.

These are simple timings. Ratios measured as Unsafe:Safe

match 1000 bytes 1 : 3.9
match 20 bytes 1 : 2.1
match 4 bytes 1 : 1.05
1st byte fail 1 : 0.45
2nd byte fail 1 : 0.6
3rd byte fail 1 : 0.7
4th byte fail 1 : 0.9
5th byte fail 1 : 0.95

When large parts of big arrays has to be compared the difference in
performance approaches 4. This is pretty much expected since the byte
version has to loop and compare 4 times as much.

With byte arrays of size 20 the unsafe version is still twice as fast.
With a really small array, and/or if the comparisons fail in the first
few bytes the advantage turns to the safe version. If the first byte
fails the safe version is more than twice as fast. The overhead of the
unsafe version is too large.

I also can't explain why the "match 4 bytes" differs slightly from
"4th byte fail". From just looking at the code I expected them to
perform the same.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top