Advertisement
Guest User

C# Fast ByteArray Comparison

a guest
Apr 8th, 2015
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.66 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Runtime.InteropServices;
  6.  
  7. public class Program
  8. {
  9.     public static void Main()
  10.     {
  11.         Tuple<byte[], byte[], byte[]>[] testdata = _createTestData().ToArray();
  12.  
  13.         Stopwatch swPinvoke = new Stopwatch();
  14.         Stopwatch swStruct = new Stopwatch();
  15.         Stopwatch swSequenceEqual = new Stopwatch();
  16.         for (int i = 0; i < 1000; i++)
  17.         {
  18.             foreach (Tuple<byte[], byte[], byte[]> testitems in testdata)
  19.             {
  20.                 swStruct.Start();
  21.                 if (ByteArrayCompare(testitems.Item1, testitems.Item2))
  22.                     throw new Exception();
  23.                 if (!ByteArrayCompare(testitems.Item1, testitems.Item3))
  24.                     throw new Exception();
  25.                 swStruct.Stop();
  26.  
  27.                 swPinvoke.Start();
  28.                 if (PInvokeCompare(testitems.Item1, testitems.Item2))
  29.                     throw new Exception();
  30.                 if (!PInvokeCompare(testitems.Item1, testitems.Item3))
  31.                     throw new Exception();
  32.                 swPinvoke.Stop();
  33.  
  34.                 swSequenceEqual.Start();
  35.                 if (testitems.Item1.SequenceEqual((testitems.Item2)))
  36.                     throw new Exception();
  37.                 if (!testitems.Item1.SequenceEqual((testitems.Item3)))
  38.                     throw new Exception();
  39.                 swSequenceEqual.Stop();
  40.  
  41.             }
  42.         }
  43.  
  44.         Console.WriteLine("PINVOKE:       {0}", swPinvoke.Elapsed);
  45.         Console.WriteLine("BITCONVERTER:  {0}", swStruct.Elapsed);
  46.         Console.WriteLine("SEQEQUAL:      {0}", swSequenceEqual.Elapsed);
  47.         Console.ReadKey();
  48.     }
  49.  
  50.     private static IEnumerable<Tuple<byte[], byte[], byte[]>> _createTestData()
  51.     {
  52.         for (int i = 1; i < 256; i++)
  53.         {
  54.             byte[] array1 = Enumerable.Range(0, i).Select(i1 => (byte) i1).ToArray();
  55.             byte[] array2 = Enumerable.Range(0, i).Select(i1 => (byte) i1).ToArray();
  56.             byte[] array3 = array1.ToArray();
  57.             // Last element in array is different (worst case)
  58.             array2[array2.Length - 1] -= 1;
  59.  
  60.             yield return Tuple.Create(array1, array2, array3);
  61.         }
  62.     }
  63.  
  64.     public static bool ByteArrayCompare(byte[] array1, byte[] array2)
  65.     {
  66.     /*    if (array1 == null) throw new ArgumentNullException("array1");
  67.         if (array2 == null) throw new ArgumentNullException("array2");
  68.  
  69.         if (ReferenceEquals(array1, array2))
  70.             return true;*/
  71.  
  72.         if (array1.Length != array2.Length)
  73.             return false;
  74.  
  75.         const int sizeOfUint64 = sizeof (UInt64);
  76.         int length = array1.Length;
  77.  
  78.  
  79.         for (int offset = 0; offset < length; offset += sizeOfUint64)
  80.         {
  81.             if (offset + sizeOfUint64 > length)
  82.             {
  83.                 for (int j = offset; j < length; j++)
  84.                 {
  85.                     if (array1[j] != array2[j])
  86.                         return false;
  87.                 }
  88.             }
  89.             else if (BitConverter.ToUInt64(array1, offset) != BitConverter.ToUInt64(array2, offset))
  90.                 return false;
  91.         }
  92.         return true;
  93.     }
  94.  
  95.     [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
  96.     static extern int memcmp(byte[] b1, byte[] b2, long count);
  97.  
  98.     public static bool PInvokeCompare(byte[] b1, byte[] b2)
  99.     {
  100.         // Validate buffers are the same length.
  101.         // This also ensures that the count does not exceed the length of either buffer.  
  102.         return b1.Length == b2.Length && memcmp(b1, b2, b1.Length) == 0;
  103.     }
  104. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement