如何在堆栈上分配数组以提高性能?
How to allocate arrays on the stack for performance gains?
一些最佳版本的函数,如 popcount
和 count consecutive zeros
使用 table 查找来获得最终答案。
在 C 和 C++ 中,可以在堆栈上分配数组并快速访问它们。
有没有办法在 C# 中做到这一点?据我所知,stackalloc
只能在函数中使用,因此数组不会持久化。
我有一个小查找 table,我希望能够尽快访问它,因此我更愿意在堆栈而不是堆上分配它。
I have a small lookup table that I'd like to be able to access as quickly as possible and thus would prefer to allocate it on the stack rather than heap.
这个说法令人困惑。将某些东西放在堆栈上意味着每次进入声明它的函数时都必须重新初始化它。通常 "optimization" 是将此类数据存储在持久位置,例如静态变量。
例如,popcount()
实施示例来自 Hamming weight 维基百科文章:
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
关键字来明确此对象只会被初始化一次。
(显然,在这两个示例中,数组中的注释都被实际值替换。或者,它们可以在运行时计算一次并保存到数组中)。
从你的问题来看,你似乎至少对堆栈、堆和数据段(即从可执行映像直接读取到内存中的特殊内存范围)有点困惑。为了提高性能,如果您要处理经常分配的固定大小的对象并且您不想承受通过内存管理器进行分配的成本,则堆栈分配很有用。
但是在实际 访问 数据方面,在堆栈上进行分配不会提供任何性能优势,而且在 [=37] 方面肯定也不会提供任何性能优势=]正在初始化数据。实际上,在后一种情况下,它会花费更多,因为每次进入该函数时都必须对其进行初始化。
我相信以上应该足以解决您的问题。但如果不是,请查看您实际尝试做的是什么,并编辑您的问题以使其更清楚。您可以查看 How do I ask a good question 以获取有关如何以清晰、可回答的方式更好地提出问题的建议。
一些最佳版本的函数,如 popcount
和 count consecutive zeros
使用 table 查找来获得最终答案。
在 C 和 C++ 中,可以在堆栈上分配数组并快速访问它们。
有没有办法在 C# 中做到这一点?据我所知,stackalloc
只能在函数中使用,因此数组不会持久化。
我有一个小查找 table,我希望能够尽快访问它,因此我更愿意在堆栈而不是堆上分配它。
I have a small lookup table that I'd like to be able to access as quickly as possible and thus would prefer to allocate it on the stack rather than heap.
这个说法令人困惑。将某些东西放在堆栈上意味着每次进入声明它的函数时都必须重新初始化它。通常 "optimization" 是将此类数据存储在持久位置,例如静态变量。
例如,popcount()
实施示例来自 Hamming weight 维基百科文章:
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
关键字来明确此对象只会被初始化一次。
(显然,在这两个示例中,数组中的注释都被实际值替换。或者,它们可以在运行时计算一次并保存到数组中)。
从你的问题来看,你似乎至少对堆栈、堆和数据段(即从可执行映像直接读取到内存中的特殊内存范围)有点困惑。为了提高性能,如果您要处理经常分配的固定大小的对象并且您不想承受通过内存管理器进行分配的成本,则堆栈分配很有用。
但是在实际 访问 数据方面,在堆栈上进行分配不会提供任何性能优势,而且在 [=37] 方面肯定也不会提供任何性能优势=]正在初始化数据。实际上,在后一种情况下,它会花费更多,因为每次进入该函数时都必须对其进行初始化。
我相信以上应该足以解决您的问题。但如果不是,请查看您实际尝试做的是什么,并编辑您的问题以使其更清楚。您可以查看 How do I ask a good question 以获取有关如何以清晰、可回答的方式更好地提出问题的建议。