How to quickly zero out an array?

后端 未结 7 922
青春惊慌失措
青春惊慌失措 2020-12-08 18:30

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.

相关标签:
7条回答
  • 2020-12-08 18:44

    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.

    0 讨论(0)
  • 2020-12-08 18:44

    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

    0 讨论(0)
  • 2020-12-08 18:46

    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();
    
    0 讨论(0)
  • 2020-12-08 18:49
    • C++: memset(array, 0, array_length_in_bytes);

    • C++11: array.fill(0);

    • C#: Array.Clear(array, startingIndex, length);

    • Java: Arrays.fill(array, value);

    0 讨论(0)
  • 2020-12-08 18:54

    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
    
    0 讨论(0)
  • 2020-12-08 19:07

    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.

    0 讨论(0)
提交回复
热议问题