C# 如何快速将数组清零?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1407715/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to quickly zero out an array?
提问by esac
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?
我目前正在 for 循环中执行此操作,并且我知道在 C 中有 ZeroMemory API,但是在 C# 中似乎不可用。也不存在与 Java 相当的 Array.fill。我只是想知道是否有更简单/更快的方法?
采纳答案by Jason Punyon
Try Array.Clear():
Sets a range of elements in the Array to zero, to
false
, or tonull
(Nothing in Visual Basic), depending on the element type.
根据元素类型,将 Array 中的元素范围设置为零、to
false
或 tonull
(在 Visual Basic 中为 Nothing)。
回答by Dustin Getz
Array.Clear(integerArray, 0, integerArray.Length);
回答by Chap
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++:
memset(array, 0, array_length_in_bytes);
C++11:
array.fill(0);
C#:
Array.Clear(array, startingIndex, length);
爪哇:
Arrays.fill(array, value);
回答by Dustin Getz
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 循环的性能都与 memset 或 FillMemory 或其他任何东西相同。
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.
例如,编译器可能会将其分块为 64 位对齐的部分,以利用 64 位零赋值指令(如果可用)。它将考虑对齐和内容。Memset 的实现当然不是微不足道的。
one memset.asm. Also see memset-is-faster-than-simple-loop.html.
一个memset.asm。另请参阅memset-is-faster-than-simple-loop.html。
Never underestimate the infinite deviousness of compiler and standard library writers.
永远不要低估编译器和标准库编写者的无限狡猾。
回答by AlexMelw
UPDATE
更新
Based on the benchmarkregarding Array.Clear()
and array[x] = default(T)
performance, we can state that there are two major casesto be considered when zeroing an array:
基于该基准关于Array.Clear()
和array[x] = default(T)
性能,我们可以说有两个主要案件零的数组时,需要考虑:
A) There is an array that is 1..76 items long;
A) 有一个长度为1..76 项的数组;
B) There is an array that is 77 or more items long.
B) 有一个长度为77 项或更多项的数组。
So the orangeline on the plot represents Array.Clear()
approach.
所以图中的橙色线代表Array.Clear()
接近。
The blueline on the plot represents array[x] = default(T)
approach (iteration over the array and setting its values to default(T)
).
图中的蓝线表示array[x] = default(T)
方法(对数组进行迭代并将其值设置为default(T)
)。
You can write once a Helper to do this job, like this:
您可以编写一次 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);
}
}
}
Usage:
用法:
someArray.SelfSetToDefaults();
回答by Reaven Clan
Calling the method by using dll import.Its fast and easy to use :)
使用 dll 导入调用该方法。它快速且易于使用:)
[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
c 是你要在内存中设置的值
OR
或者
[DllImport("kernel32.dll", EntryPoint="RtlZeroMemory")]
public unsafe static extern bool ZeroMemory(byte* destination, int length);
this only sets the given array to zero
这只会将给定的数组设置为零
回答by IBeThieving
I believe this is what you're looking for I wrote this in visual basic however I'm sure you can convert it.
我相信这就是你要找的东西,我是用 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