I pine for the days when, as a C programmer, I could type:
memset( byte_array, '0xFF' );
and get a byte array filled with 'FF' characters. So, I have been looking for a replacement for this:
for (int i=0; i < byteArray.Length; i++)
{
byteArray[i] = 0xFF;
}
Lately, I have been using some of the new C# features and have been using this approach instead:
Array.ForEach<byte>(byteArray, b => b = 0xFF);
Granted, the second approach seems cleaner and is easier on the eye, but how does the performance compare to using the first approach? Am I introducing needless overhead by using Linq and generics?
Thanks, Dave
Array.ForEach<byte>(byteArray, b => b = 0xFF);
This doesn't do anything. It's setting a copy of each byte to 0xFF, it never gets set in the array.
For an easier way to do this, you could try
Enumerable.Repeat((byte)0xFF, someCount).ToArray();
to initialize your array
Repeat will definitely be slower than your for loop. According to the link posted by CAbbott in a comment, it's about 10.5 seconds slower (12.38 vs 1.7) on an array with over a million items, but that isn't a big difference if you're only doing it a few times with small arrays.
You could write a simple method that will be quicker than Repeat and ToArray because you can know the length of the array before you start filling it.
public static T[] GetPreFilledArray<T>(T fillItem, int count)
{
var result = new T[count];
for(int i =0; i < count; i++)
{
result[i] = fillItem;
}
return result;
}
byte[] byteArray = GetPreFilledArray((byte)0xFF, 1000);
That should be a pretty quick option, as it's basically what you're doing now.
The second method uses a delegate to set each byte, this means that there is a method call for every byte in the array. That's a lot of overhead just to set a byte.
The plain loop on the other hand gets optimised rather well by the compiler. It will determine that the index can not be outside the array, so it will skip the bounds checking.
To clarify: You are not using LINQ at all. The ForEach method is a method in the Array class, and it predates the addition of LINQ.
Buffer.BlockCopy is what I tend to use when I want memset/memcpy type behavior. I would measure the performance and use something like reflector. It may be that internally the language calls the built-in classes, which in turn are thin wrappers around MEMCPY and MEMSET.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With