How to quickly zero out an array?

C#ArraysMemory

C# Problem Overview


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?

C# Solutions


Solution 1 - C#

Try Array.Clear():

> Sets a range of elements in the Array > to zero, to false, or to > null > (Nothing in Visual Basic), depending > on the element type.

Solution 2 - C#

  • 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 - C#

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)).

enter image description here

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 - C#

Array.Clear(integerArray, 0, integerArray.Length);

Solution 5 - C#

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.

Solution 6 - C#

Calling the method by using dll import.Its fast and easy to use :)

 [DllImport("msvcrt.dll", EntryPoint = "memset", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
 public static extern IntPtr MemSet(IntPtr dest, int c, int byteCount);

c is the value you want to set in the memory

OR

[DllImport("kernel32.dll", EntryPoint="RtlZeroMemory")]
public unsafe static extern bool ZeroMemory(byte* destination, int length);

this only sets the given array to zero

Solution 7 - C#

I believe this is what you're looking for I wrote this in visual basic however I'm sure you can convert it.

Imports System.Runtime.InteropServices

Module Module1

    'import Kernel32 so we can use the ZeroMemory Windows API function
    <DllImport("kernel32.dll")>
    Public Sub ZeroMemory(ByVal addr As IntPtr, ByVal size As IntPtr)

    End Sub

    Private Sub ZeroArray(array As ArrayList)
        'Iterate from 0 to the lenght of the array zeroing each item at that index
        For i As Integer = 0 To array.Count - 1
            'Pin the array item in memory
            Dim gch As GCHandle = GCHandle.Alloc((array(i)), GCHandleType.Pinned)
            'Get the memory address of the object pinned
            Dim arrayAddress As IntPtr = gch.AddrOfPinnedObject()
            'Get size of the array
            Dim arraySize As IntPtr = CType(array.Count, IntPtr)
            'Zero memory at the current index address in memory
            ZeroMemory(arrayAddress, arraySize)
            gch.Free()
        Next

    End Sub


    Sub Main()
        'Initialize ArrayList with items
        Dim strArray As New ArrayList From {
            "example one",
            "example two",
            "example three"
        }

        'Pass array as parameter to a function which will iterate through the arraylist zeroing each item in memory
        ZeroArray(strArray)

        Console.ReadLine()
    End Sub

End Module

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionesacView Question on Stackoverflow
Solution 1 - C#Jason PunyonView Answer on Stackoverflow
Solution 2 - C#ChapView Answer on Stackoverflow
Solution 3 - C#AlexMelwView Answer on Stackoverflow
Solution 4 - C#Dustin GetzView Answer on Stackoverflow
Solution 5 - C#Dustin GetzView Answer on Stackoverflow
Solution 6 - C#Reaven ClanView Answer on Stackoverflow
Solution 7 - C#IBeThievingView Answer on Stackoverflow