Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. memcmp in C#

memcmp in C#

Scheduled Pinned Locked Moved C#
csharp
7 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    BrcKcc
    wrote on last edited by
    #1

    I want to compare two byte buffer quickly. I used to do this with memcmp in C. I can't find a function to do that in C#. I'm sure there is one, but I can't find it. BRCKCC

    H 1 Reply Last reply
    0
    • B BrcKcc

      I want to compare two byte buffer quickly. I used to do this with memcmp in C. I can't find a function to do that in C#. I'm sure there is one, but I can't find it. BRCKCC

      H Offline
      H Offline
      Heath Stewart
      wrote on last edited by
      #2

      There really isn't a way as fast as memcmp, so if you need that kind of performance, you can always P/Invoke it:

      using System;
      using System.Runtime.InteropServices;

      class Test
      {
      static void Main()
      {
      byte[] b1 = new byte[10];
      byte[] b2 = new byte[10];

      for (int i=0; iThis would print:
      

      Equals: False
      Object.Equals: False
      memcmp: True

      By doing this you sacrific portability, however. If you don't need that kind of performance, use a simple for (not foreach, which is slower) loop and compare each byte using the == equivalency operator.

      Microsoft MVP, Visual C#
      My Articles

      B 1 Reply Last reply
      0
      • H Heath Stewart

        There really isn't a way as fast as memcmp, so if you need that kind of performance, you can always P/Invoke it:

        using System;
        using System.Runtime.InteropServices;

        class Test
        {
        static void Main()
        {
        byte[] b1 = new byte[10];
        byte[] b2 = new byte[10];

        for (int i=0; iThis would print:
        

        Equals: False
        Object.Equals: False
        memcmp: True

        By doing this you sacrific portability, however. If you don't need that kind of performance, use a simple for (not foreach, which is slower) loop and compare each byte using the == equivalency operator.

        Microsoft MVP, Visual C#
        My Articles

        B Offline
        B Offline
        BrcKcc
        wrote on last edited by
        #3

        I'm using the for loop and since I don't want to sacrifice portability, I'll stick with the for loop. Thanks. - Bruce BRCKCC

        W 1 Reply Last reply
        0
        • B BrcKcc

          I'm using the for loop and since I don't want to sacrifice portability, I'll stick with the for loop. Thanks. - Bruce BRCKCC

          W Offline
          W Offline
          Werdna
          wrote on last edited by
          #4

          Also, if you'd be allowed to use unsafe code, it would be much faster. You'd be able to loop thru the array cast to array of ints and comparing 4 bytes at a time. Plus the CPU works better with int values than single byte values. Of course you'd have to have a special case for padding bytes.

          B 1 Reply Last reply
          0
          • W Werdna

            Also, if you'd be allowed to use unsafe code, it would be much faster. You'd be able to loop thru the array cast to array of ints and comparing 4 bytes at a time. Plus the CPU works better with int values than single byte values. Of course you'd have to have a special case for padding bytes.

            B Offline
            B Offline
            BrcKcc
            wrote on last edited by
            #5

            Do you have a snippet of code on how to do this "casting"? BRCKCC

            W 1 Reply Last reply
            0
            • B BrcKcc

              Do you have a snippet of code on how to do this "casting"? BRCKCC

              W Offline
              W Offline
              Werdna
              wrote on last edited by
              #6

              Here is a simple program that tests the comparison using safe and unsafe version. On my machine the unsafe version is about 4 times as fast as safe version. You have to make sure you allow unsafe code in project properties. Note, this will only work with arrays whose size is divisble by 4. You can easily change it to handle the last 1, 2 or 3 bytes specially, but i'll leave it as excercise.

              using System;
              
              namespace Tester
              {
              	class Class1
              	{
              		[STAThread]
              		static void Main(string[] args)
              		{
              			const int repeats = 200;
              
              			byte[] bytes1 = randomBytes(4 * 1000000);
              			byte[] bytes2 = new byte[bytes1.Length];
              			for (int i=0; i<bytes1.Length; i++)
              				bytes1[i] = bytes2[i];
              
              
              			// unsafe version
              			int start_t = System.Environment.TickCount;
              			for (int r=1; r<=repeats; r++)
              			{
              				bool res = CompareUnsafe(bytes1, bytes2);
              
              				if (r == repeats)
              					Console.WriteLine("Result: " + res);
              			}
              			int end_t = System.Environment.TickCount;
              			Console.WriteLine("CompareUnsafe: {0} ms.", (end_t-start_t));
              
              			// safe version
              			start_t = System.Environment.TickCount;
              			for (int r=1; r<=repeats; r++)
              			{
              				bool res = CompareSafe(bytes1, bytes2);
              
              				if (r == repeats)
              					Console.WriteLine("Result: " + res);
              			}
              			end_t = System.Environment.TickCount;
              			Console.WriteLine("CompareSafe: {0} ms.", (end_t-start_t));
              		}
              
              		public static bool CompareSafe(byte[] byteArray1, byte[] byteArray2)
              		{
              			if (byteArray1.Length != byteArray2.Length)
              				return false;
              
              			for (int i=0; i<byteArray1.Length; i++)
              				if (byteArray1[i] != byteArray2[i])
              					return false;
              
              			return true;
              		}
              
              		public unsafe static bool CompareUnsafe(byte[] byteArray1, byte[] byteArray2)
              		{
              			if (byteArray1.Length != byteArray2.Length)
              				return false;
              
              			if (byteArray1.Length % 4 != 0)
              				throw new ArgumentException("Byte arrays have to be divisible by 4", "bytearray");
              
              			fixed (byte* bytes1 = &(byteArray1[0]))
              			fixed (byte* bytes2 = &(byteArray2[0]))
              			{
              				int* ints1 = (int*)bytes1;
              				int* ints2 = (int*)bytes2;
              				int size = byteArray1.Length / 4;
              				for (int i=0; i<size; i++)
              					if (ints1[i] != ints2[i])
              						return false;
              
              			}
              
              			// all comparisons succeeded
              			return true;
              		}
              
              		public static byte[] randomBytes(int size)
              		{
              			Random r = new Random();
              			byte[] bytes = new byte[size];
              			r.NextBytes(bytes);
              
              			return bytes;
              		}
              	}
              }
              
              B 1 Reply Last reply
              0
              • W Werdna

                Here is a simple program that tests the comparison using safe and unsafe version. On my machine the unsafe version is about 4 times as fast as safe version. You have to make sure you allow unsafe code in project properties. Note, this will only work with arrays whose size is divisble by 4. You can easily change it to handle the last 1, 2 or 3 bytes specially, but i'll leave it as excercise.

                using System;
                
                namespace Tester
                {
                	class Class1
                	{
                		[STAThread]
                		static void Main(string[] args)
                		{
                			const int repeats = 200;
                
                			byte[] bytes1 = randomBytes(4 * 1000000);
                			byte[] bytes2 = new byte[bytes1.Length];
                			for (int i=0; i<bytes1.Length; i++)
                				bytes1[i] = bytes2[i];
                
                
                			// unsafe version
                			int start_t = System.Environment.TickCount;
                			for (int r=1; r<=repeats; r++)
                			{
                				bool res = CompareUnsafe(bytes1, bytes2);
                
                				if (r == repeats)
                					Console.WriteLine("Result: " + res);
                			}
                			int end_t = System.Environment.TickCount;
                			Console.WriteLine("CompareUnsafe: {0} ms.", (end_t-start_t));
                
                			// safe version
                			start_t = System.Environment.TickCount;
                			for (int r=1; r<=repeats; r++)
                			{
                				bool res = CompareSafe(bytes1, bytes2);
                
                				if (r == repeats)
                					Console.WriteLine("Result: " + res);
                			}
                			end_t = System.Environment.TickCount;
                			Console.WriteLine("CompareSafe: {0} ms.", (end_t-start_t));
                		}
                
                		public static bool CompareSafe(byte[] byteArray1, byte[] byteArray2)
                		{
                			if (byteArray1.Length != byteArray2.Length)
                				return false;
                
                			for (int i=0; i<byteArray1.Length; i++)
                				if (byteArray1[i] != byteArray2[i])
                					return false;
                
                			return true;
                		}
                
                		public unsafe static bool CompareUnsafe(byte[] byteArray1, byte[] byteArray2)
                		{
                			if (byteArray1.Length != byteArray2.Length)
                				return false;
                
                			if (byteArray1.Length % 4 != 0)
                				throw new ArgumentException("Byte arrays have to be divisible by 4", "bytearray");
                
                			fixed (byte* bytes1 = &(byteArray1[0]))
                			fixed (byte* bytes2 = &(byteArray2[0]))
                			{
                				int* ints1 = (int*)bytes1;
                				int* ints2 = (int*)bytes2;
                				int size = byteArray1.Length / 4;
                				for (int i=0; i<size; i++)
                					if (ints1[i] != ints2[i])
                						return false;
                
                			}
                
                			// all comparisons succeeded
                			return true;
                		}
                
                		public static byte[] randomBytes(int size)
                		{
                			Random r = new Random();
                			byte[] bytes = new byte[size];
                			r.NextBytes(bytes);
                
                			return bytes;
                		}
                	}
                }
                
                B Offline
                B Offline
                BrcKcc
                wrote on last edited by
                #7

                Thanks very much. - Bruce :) BRCKCC

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups