我目前正在for循环中进行,我知道在C中有ZeroMemory API,但是C#似乎没有。也不存在来自Java的有点等效的Array.fill。我只是想知道是否有更容易/更快的方式?
答案 0 :(得分:98)
设置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)
)。
你可以写一次帮手来完成这项工作,如下:
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