如何在堆栈上分配数组以获得性能提升?

时间:2015-03-29 00:00:29

标签: c# arrays performance stack heap

popcountcount consecutive zeros等功能的一些最佳版本使用表格查找来获得最终答案。

在C和C ++中,可以在堆栈上分配数组并快速访问它们。

有没有办法在C#中执行此操作?据我所知,stackalloc只能在函数中使用,因此数组不会持久存在。

我有一个小的查找表,我希望能够尽快访问,因此更愿意将它分配到堆栈而不是堆。

1 个答案:

答案 0 :(得分:3)

  

我有一个小的查找表,我希望能够尽快访问,因此更愿意将它分配到堆栈而不是堆。

这句话令人困惑。将东西放在堆栈上意味着每次进入它声明的函数时都必须重新初始化。通常"优化"而是将此类数据存储在持久位置,例如静态变量。

例如,这是Hamming weight维基百科文章中的popcount()示例实例:

static uint8_t wordbits[65536] = { /* bitcounts of integers 0 through 65535, inclusive */ };
static int popcount(uint32_t i)
{
    return (wordbits[i&0xFFFF] + wordbits[i>>16]);
}

请注意,wordbits数组在任何函数的声明为static变量。

C#中的类似声明将是这样的:

static readonly byte[] wordbits = { /* bitcounts of integers 0 through 65535, inclusive */  };
static int popcount(uint i)
{
    return (wordbits[i & 0xFFFF] + wordbits[i >> 16]);
}

请注意使用C#的readonly关键字来明确该对象只会被初始化一次。

(显然,在两个示例中,数组中的注释都被实际值替换。或者,它们可以在运行时计算一次并保存到数组中。)

从您的问题来看,似乎您可能至少对堆栈与堆与数据段(即从可执行映像直接读取到内存中的特殊内存范围)感到困惑。对于性能,如果您处理经常分配的固定大小的对象并且您不想承担通过内存管理器分配的成本,则堆栈分配非常有用。

但是,在实际上访问数据方面,在堆栈上分配并不能提供任何性能优势,并且在初始化方面肯定也没有提供任何性能优势数据。实际上,就后者而言,它会花费更多,因为每次进入该功能时都必须对其进行初始化。

我认为上述内容应该充分解决您的担忧。但如果没有,请查看您实际尝试做的事情,并编辑您的问题,以便更清楚。您可以查看How do I ask a good question,了解如何以清晰,可回答的方式更好地展示您的问题。