Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET + Copying large amounts of memory tricks

Back in the olden days, there were tricks used (often for blitting offscreen framebuffers), to copy large chunks of memory from one location to another.

Now that I'm working in C#, I've found the need to move an array of bytes (roughly 32k in size) from one memory location to another approximately 60 times per second.

Somehow, I don't think a byte by byte copy in a for loop is optimal here.

Does anyone know a good trick to do this kinda of work while still staying in purely managed code?

If not, I'm willing to do some P/Invoking or go into unsafe mode, but I'd like to stay managed if I can for cross platform reasons.

EDIT: Some benchmarking code I wrote up just for fun:

Byte by Byte: 15.6192

4 Bytes per loop: 15.6192

Block Copy: 0

Byte[] src = new byte[65535];
            Byte[] dest = new byte[65535];
            DateTime startTime, endTime;

            startTime = DateTime.Now;
            for (int k = 0; k < 60; k++)
            {
                for (int i = 0; i < src.Length; i++)
                {
                    dest[i] = src[i];
                }
            }
            endTime = DateTime.Now;

            Console.WriteLine("Byte by Byte: " + endTime.Subtract(startTime).TotalMilliseconds);

            startTime = DateTime.Now;
            for (int k = 0; k < 60; k++)
            {
                int i = 0;
                while (i < src.Length)
                {
                    if (i + 4 > src.Length)
                    {
                        // Copy the remaining bytes one at a time.
                        while(i < src.Length)
                        {
                            dest[i] = src[i];
                            i++;
                        }
                        break;
                    }
                    
                    dest[i] = src[i];
                    dest[i + 1] = src[i + 1];
                    dest[i + 2] = src[i + 2];
                    dest[i + 3] = src[i + 3];

                    i += 4;                    
                }
            }
            endTime = DateTime.Now;

            Console.WriteLine("4 Bytes per loop: " + endTime.Subtract(startTime).TotalMilliseconds);

            startTime = DateTime.Now;
            for (int k = 0; k < 60; k++)
            {
                Buffer.BlockCopy(src, 0, dest,0, src.Length);
            }
            endTime = DateTime.Now;

            Console.WriteLine("Block Copy: " + endTime.Subtract(startTime).TotalMilliseconds);
like image 718
FlySwat Avatar asked Mar 02 '23 07:03

FlySwat


1 Answers

I think you can count on Buffer.BlockCopy() to do the right thing

http://msdn.microsoft.com/en-us/library/system.buffer.blockcopy.aspx

like image 64
Lou Franco Avatar answered Mar 05 '23 16:03

Lou Franco