C# Buffer.BlockCopy Method

Buffer conceptual image

Buffer.BlockCopy optimizes large array copies. It copies ranges of bytes from one array to another. It does not copy logical elements in those arrays. This yields a significant performance boost in some programs.

These C# examples demonstrate the Buffer.BlockCopy method. This method copies memory, not elements.

Copy byte arrays

First, here we see how you can call Buffer.BlockCopy to copy the bytes in one byte array to another. This can be useful for compression, images, or many other types of binary data.

Program that uses BlockCopy on bytes [C#]

using System;

class Program
{
    static void Main()
    {
	byte[] arr1 = new byte[] { 1, 2, 3, 4, 5 };
	byte[] arr2 = new byte[10];

	// Copy the first five bytes from arr1 to arr2
	Buffer.BlockCopy(arr1, 0, arr2, 0, 5);

	Display(arr2);
    }

    static void Display(byte[] arr)
    {
	for (int i = 0; i < arr.Length; i++)
	{
	    Console.Write(arr[i]);
	}
	Console.WriteLine();
    }
}

Output

1234500000
.NET Framework information

Description. The Display method shown demonstrates that we get the expected result after calling Buffer.BlockCopy. Note that the ints are actually used as bytes, not 4-byte ints. The byte[] array arr2 is automatically initialized to all zero bytes, which is the behavior of .NET on new arrays.

Copy int arrays

Int keyword

Here we see that the usage of Buffer.BlockCopy is different slightly when using a data type that is not 1 byte. In the C# language, an int is 4 bytes, which is four times larger than the byte type. The fifth parameter of Buffer.BlockCopy is the number of bytes to copy, not array elements. Therefore, we must multiply it by 4, or the sizeof(int).

Program that copies ints [C#]

using System;

class Program
{
    static void Main()
    {
	int[] arr1 = new int[] { 1, 2, 3, 4, 5 };
	int[] arr2 = new int[10];

	// Copy the first twenty bytes from arr1 to arr2
	Buffer.BlockCopy(arr1, 0, arr2, 0, 5 * sizeof(int));

	Display(arr2);
    }

    static void Display(int[] arr)
    {
	for (int i = 0; i < arr.Length; i++)
	{
	    Console.Write(arr[i]);
	}
	Console.WriteLine();
    }
}

Output

1234500000

Description. The sizeof() operator is a way to have the compiler return the byte length of a primitive data type like int. Here it returns 4. The multiplication of sizeof(int) * 4 can be resolved by the C# compiler, meaning it won't cause any slowdowns. With Buffer.BlockCopy, this is important.

Benchmark

Performance optimization

To test Buffer.BlockCopy further, I benchmarked it on a 1000-element array. I found it has a significant performance advantage over Array.Copy. Additionally, copying the elements in a for loop was far slower.

Array.Copy
Method that returns byte arrays [C#]

static byte[] GetSourceArray()
{
    // [Note] You can populate data here
    return new byte[_len];
}

Code that copies byte arrays [C#]
    Iterations tested: 10000000

const int _len = 1000;

Buffer.BlockCopy(source, 0, target, 0, _len);

Array.Copy(source, target, _len);

Results. The benchmark tested an array of 1000 random byte values, but these did not affect behavior in any way, as expected. The code here doesn't include that part.

Benchmark results

Buffer.BlockCopy: 1113 ms [faster]
Array.Copy:       1343 ms

Summary

The C# programming language

We saw how to use Buffer.BlockCopy on int[] and byte[] arrays using the C# programming language, and I proved the correctness of the example results for those types. Finally, we demonstrated the performance improvement when using Buffer.BlockCopy in a micro-benchmark. Please see the related information on the Buffer.ByteLength method.

ByteLength Array Types
.NET