Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#中的数组何时进行零填充操作?_C#_Arrays_Performance_Initialization - Fatal编程技术网

C#中的数组何时进行零填充操作?

C#中的数组何时进行零填充操作?,c#,arrays,performance,initialization,C#,Arrays,Performance,Initialization,在C#中考虑这一点: 所有整数都将设置为0。传统上,这是通过高度优化的零填充操作完成的(例如memset)。然而,由于这个数组是由CLR分配的,我可以想到一个非常直接的优化;CLR可以维护一个归零的内存区域,以便在我们请求内存时跳过此归零填充 现在,CLR是否执行这样的优化?(我目前使用的是.NET 4.0)CLR只分配一个比托管堆消耗的内存多的内存,如果托管堆的未分配内存用完,它将从操作系统请求更多内存。只有当您的进程将内存设置为已经很大,并且有大量未使用的内存被垃圾回收时,才能利用内存预调零

在C#中考虑这一点:

所有整数都将设置为0。传统上,这是通过高度优化的零填充操作完成的(例如
memset
)。然而,由于这个数组是由CLR分配的,我可以想到一个非常直接的优化;CLR可以维护一个归零的内存区域,以便在我们请求内存时跳过此归零填充


现在,CLR是否执行这样的优化?(我目前使用的是.NET 4.0)

CLR只分配一个比托管堆消耗的内存多的内存,如果托管堆的未分配内存用完,它将从操作系统请求更多内存。只有当您的进程将内存设置为已经很大,并且有大量未使用的内存被垃圾回收时,才能利用内存预调零。然后,该内存可以从托管堆中自由分配。
如果您的应用程序是这样,您应该考虑重用阵列,而不是丢弃阵列,以避免在托管堆上重新分配。

您看过为该代码生成的IL了吗?可能会为相关调用生成对
newarr
的调用。根据ECMA-355,
newarr
创建一个新的基于零的一维数组,并将数组元素初始化为适当类型的0。在这种情况下,由于它是
int
的数组,因此元素在创建时将被初始化为0。

这在一个低得多的级别上运行。Windows使低优先级内核线程保持活动状态,其唯一任务是将内存页的内容归零。称为“零页线程”。这些页面保存在一个池中,可以用于为保留但未提交的页面生成页面错误的任何进程。Windows中的任何代码都可以从中受益,而不仅仅是托管代码。其目的是安全性,而不是将映射内存页的RAM内容归零将允许程序监视另一个进程的内存


您的阵列不会发生这种情况,它太小了。它在gen#0堆中分配,该堆将始终具有映射页面。然而,大型数组在大型对象堆中分配,大型为85000字节,双字节数组为8000字节。LOH分配可以利用将页面预初始化为零的优势。很难说它是否真的这样做了,它的源代码在任何地方都不可用。我认为这可能是考虑到它节省的cpu周期。

你为什么会在意?当然,除了学术兴趣之外,我碰巧已经从C++世界中成长了,程序员们实际上关心的是底层代码。(而且……在CPU密集型算法中处理巨大的内存块时,不必要的归零可能会成为瓶颈。知道何时发生归零是有意义的。)“你为什么会在意?”-提醒我不,它不会为结构调用构造函数。结构没有无参数实例构造函数(规范中的11.3.8)。通过将所有值类型字段设置为默认值来初始化结构。此外,使用创建表达式(而不是初始值设定项)创建的数组元素总是初始化为其默认值。@MikeCowan您说得对,我将其与包含构造的ctor混合,并强制编译器手动初始化所有字段。从我的回答中删除了那部分。
int[] a = new int[1024];