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

一些最佳版本的函数,如popcountcount consecutive zeros使用表查找来获得最终答案。

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

有没有办法在C#中做到这一点? 据我所知, stackalloc只能在函数中使用,因此数组不会持久存在。

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

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

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

例如,这是一个来自Hamming weight Wikipedia文章的示例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关键字来表明这个对象只会被初始化一次。

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

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

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

我认为上述内容应该充分解决您的担忧。 但如果没有,请检查您实际上要做的是什么,并编辑您的问题,以便更清楚。 您可以查看我如何提出一个好问题,以获得有关如何以清晰,可回答的方式更好地呈现问题的建议。