How to quickly zero out an array?
Solution 1
Try Array.Clear():
Sets a range of elements in the Array to zero, to
false
, or tonull
(Nothing in Visual Basic), depending on the element type.
Solution 2
C++:
memset(array, 0, array_length_in_bytes);
C++11:
array.fill(0);
C#:
Array.Clear(array, startingIndex, length);
Java:
Arrays.fill(array, value);
Solution 3
UPDATE
Based on the benchmark regarding Array.Clear()
and array[x] = default(T)
performance, we can state that there are two major cases to be considered when zeroing an array:
A) There is an array that is 1..76 items long;
B) There is an array that is 77 or more items long.
So the orange line on the plot represents Array.Clear()
approach.
The blue line on the plot represents array[x] = default(T)
approach (iteration over the array and setting its values to default(T)
).
You can write once a Helper to do this job, like this:
public static class ArrayHelper
{
// Performance-oriented algorithm selection
public static void SelfSetToDefaults<T>(this T[] sourceArray)
{
if (sourceArray.Length <= 76)
{
for (int i = 0; i < sourceArray.Length; i++)
{
sourceArray[i] = default(T);
}
}
else { // 77+
Array.Clear(
array: sourceArray,
index: 0,
length: sourceArray.Length);
}
}
}
Usage:
someArray.SelfSetToDefaults();
Remarks:
This test was undertaken having in mind .NET Framework 4.x
Solution 4
Array.Clear(integerArray, 0, integerArray.Length);
Solution 5
Several people have posted answers, then deleted them, saying that in any language a for loop will be equally performant as a memset or FillMemory or whatever.
For example, a compiler might chunk it into 64-bit aligned pieces to take advantage of a 64bit zero assignment instruction, if available. It will take alignment and stuff into consideration. Memset's implementation is certainly not trivial.
one memset.asm. Also see memset-is-faster-than-simple-loop.html.
Never underestimate the infinite deviousness of compiler and standard library writers.
esac
I am a software developer primarily focused on WinForms development in C#. I have been in development for 10 years.
Updated on March 08, 2020Comments
-
esac about 4 years
I am currently doing it in a for loop, and I know in C there is the ZeroMemory API, however that doesn't seem to be available in C#. Nor does the somewhat equivalent Array.fill from Java exist either. I am just wondering if there is an easier/faster way?
-
esac over 14 yearsI did a test with my for loop vs Array.Clear(). Array.Clear() 2 million times in a loop for a 4K array took 620 ms. The for loop took 13030 ms.
-
Richard over 10 years@esac And while that definitely answers your question, it's still an open question as to whether that remains true for all operating systems and hardware. I agree that Array.Clear() is going to be at least as fast as a for loop and probably faster, which makes Array.Clear() the obvious choice. (Plus, it's easier to read.)
-
Hi-Angel almost 9 yearsI'd against the c-function
memset
in C++ in favor of the C++std::fill
. Thememset
usually in optimized code becomes a call to the librarymemset
, whilststd::fill
becomes just a few assembly instructions, without a call at all. -
Dai about 2 yearsIn .NET Framework 4.x,
Array.Clear()
is faster forN > ~75
, but in .NET 6 I see thatArray.Clear()
is now faster forN > ~25
. -
Dai about 2 years@Richard
Array.Clear()
is slower thanfor
for very small arrays (1 <= N < ~25-75
) though, owing toArray.Clear
's internal logic for parameter validation and getting the dimensions/bounds of the array.