Question

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);
Was it helpful?

Solution

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

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top