有没有人实际使用stackalloc而编程的C#?我知道的是什么呢,但它在我的代码显示了唯一的一次是偶然,因为智能感知表明它,当我开始输入static,例如。

虽然不涉及到stackalloc的使用场景,我实际上做了相当多的传统的互操作在我的应用程序,所以每一个现在,然后我可以诉诸使用unsafe代码。但尽管如此我通常会找到办法,以避免unsafe完全。

由于可在.net中一个单独的线程堆栈大小是〜1MB(纠正我,如果我错了),我甚至使用stackalloc更为内敛。

有没有一些实际的情况下,人们可以说:“这正是数据适量和处理我去不安全,并使用stackalloc

有帮助吗?

解决方案

使用stackalloc唯一原因是性能(或者用于计算或互操作)。通过使用stackalloc而不是堆分配阵列,为您打造更小GC压力(GC运行所需要的更少),你不需要针阵列下来,它的速度比堆阵列分配中,它会自动释放上方法退出(GC运行时堆分配阵列仅解除分配)。还通过使用stackalloc而不是本机分配器(如malloc的或.net当量)还获得关于范围出口速度和自动解除分配。

在性能方面,如果你使用stackalloc你大大提高缓存的CPU上的机会命中由于数据的地方。

其他提示

我已经使用stackalloc分配缓冲器为[近]实时DSP的工作。这是在性能需要尽可能一致的一个非常具体的情况。注意有一致性和总吞吐量之间的差异 - 在这种情况下,我不关心堆分配太慢,只是垃圾回收的在程序该点的非确定性。我不会在箱子99%使用。

stackalloc只对不安全代码相关。对于托管代码,你不能决定如何分配数据。值类型被分配每默认在栈上(除非它们是引用类型,在这种情况下,它们在堆上分配的一部分)。引用类型被分配在堆上。

有一个普通的.NET应用程序的缺省堆栈大小为1 MB,但可以在PE头部改变这一点。如果你明确地启动线程,你也可以通过构造函数重载设置不同的尺寸。对于ASP.NET应用程序的默认堆栈大小只有256K,这是一件好事要记住,如果你在两个环境之间切换。

跨距Stackalloc初始化。在C#的早期版本中,stackalloc的结果只能被存储到一个指针局部变量。作为C#7.2,stackalloc现在可以用作表达的一部分,并且可以针对一个跨度,并且可以在不使用不安全的关键字来完成。因此,代替书写

Span<byte> bytes;
unsafe
{
  byte* tmp = stackalloc byte[length];
  bytes = new Span<byte>(tmp, length);
}

可以简单地写为:

Span<byte> bytes = stackalloc byte[length];

<强>这也是在你需要一些暂存空间,以执行操作,但希望避免对于相对小的尺寸的分配堆内存的情况下是非常有用的

Span<byte> bytes = length <= 128 ? stackalloc byte[length] : new byte[length];
... // Code that operates on the Span<byte>

来源: C# - 所有关于跨度:探索一个新的.NET支柱

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top