如何快速清零阵列?

esa*_*sac 53 c# memory arrays

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

Jas*_*yon 103

尝试Array.Clear():

根据元素类型,将Array中的元素范围设置为零,to false或to null (在Visual Basic中为 Nothing).

  • 伙计,不知道我是怎么想念这个的,甚至不看Array类的所有成员。 (2认同)
  • @esac也许是因为«Clear()»与删除元素相关联,而不是将元素设置为零。 (2认同)

Cha*_*hap 48

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

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

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

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

  • 我反对C++中的c函数`memset`而支持C++`std :: fill`.通常在优化代码中的`memset`成为对库`memset`的调用,而`std :: fill`只是一些汇编指令,根本没有调用. (9认同)

Dus*_*etz 16

Array.Clear(integerArray, 0, integerArray.Length);
Run Code Online (Sandbox Code Playgroud)


And*_*yWD 15

UPDATE

基于该基准关于Array.Clear()array[x] = default(T)性能,我们可以说有两个主要案件零的数组时,需要考虑:

A)有一个长达1..76个项目的数组;

B)有一个长度为77或更多的数组.

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

图中的线表示array[x] = default(T)方法(迭代数组并将其值设置为default(T)).

在此输入图像描述

您可以写一次Helper来完成这项工作,如下所示:

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

someArray.SelfSetToDefaults();
Run Code Online (Sandbox Code Playgroud)

  • 在 .NET Framework 4.x 中,“Array.Clear()”对于“N &gt; ~75”更快,但在 .NET 6 中,我发现“Array.Clear()”对于“N &gt; ~25”更快。 (3认同)

Dus*_*etz 12

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

例如,编译器可能会将其块化为64位对齐的片段,以利用64位零分配指令(如果可用).它需要考虑对齐和考虑因素.Memset的实现肯定不是微不足道的.

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

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

  • 我使用for for loop和Array.Clear()进行了测试.Array.Clear()在一个4K阵列的循环中耗时200万次.for循环耗时13030毫秒. (12认同)
  • @esac虽然这肯定回答了你的问题,但对于所有操作系统和硬件是否仍然如此仍然是一个悬而未决的问题.我同意Array.Clear()至少和for循环一样快,可能更快,这使得Array.Clear()成为明显的选择.(另外,它更容易阅读.) (2认同)

Rea*_*lan 5

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

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

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

或者

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

这只会将给定数组设置为零