如何快速清零阵列?

时间:2009-09-10 21:05:17

标签: c# arrays memory

我目前正在for循环中进行,我知道在C中有ZeroMemory API,但是C#似乎没有。也不存在来自Java的有点等效的Array.fill。我只是想知道是否有更容易/更快的方式?

7 个答案:

答案 0 :(得分:98)

尝试Array.Clear()

  

设置Array中的元素范围   为零,到false或到。{   null   (取决于Visual Basic中的任何内容)   关于元素类型。

答案 1 :(得分:44)

  • C ++:memset(array, 0, array_length_in_bytes);

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

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

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

答案 2 :(得分:15)

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

答案 3 :(得分:11)

有几个人发布了答案,然后将其删除,并说在任何语言中,for循环将与memset或FillMemory或其他任何东西一样高效。

例如,编译器可能会将其块化为64位对齐的片段,以利用64位零分配指令(如果可用)。它需要考虑对齐和考虑因素。 Memset的实现当然不是一件容易的事。

一个memset.asm。另请参阅memset-is-faster-than-simple-loop.html

永远不要低估编译器和标准库编写者的无限狡猾。

答案 4 :(得分:10)

<强>更新

根据有关Array.Clear()array[x] = default(T)效果的benchmark,我们可以说明在将数组归零时需要考虑两个主要情况:< / p>

A)有一个 1..76项长;

的数组

B)有一个数组 77或更长的项目

因此图上的橙色行表示Array.Clear()方法。

图上的蓝色行代表array[x] = default(T)方法(对数组进行迭代并将其值设置为default(T))。

enter image description here

你可以写一次帮手来完成这项工作,如下:

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);
        }
    }
}

用法:

someArray.SelfSetToDefaults();

答案 5 :(得分:2)

使用dll import调用方法。它快速且易于使用:)

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

c是您要在内存中设置的值

OR

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

这只将给定数组设置为零

答案 6 :(得分:0)

我相信这就是您要寻找的内容。我用Visual Basic编写了此内容,但是我确定您可以将其转换。

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