代码如下所示:
for (int i = 0; i <= LARGE_NUMBER; ++i) {
int x[LARGE_NUMBER] = {0};
// do something with x
}
我认为每次x
通过for-loop
时都会创建数组0~LARGE_NUMBER
,所以
这会影响性能吗? -O2
会帮忙吗?
答案 0 :(得分:2)
你的数组将在每次迭代中归零,所以肯定会。
此代码是线性时间,数组的每个元素都将进行零初始化:
int x[LARGE_NUMBER] = {0};
这是常量时间,只是堆栈指针的增量:
int x[LARGE_NUMBER];
性能取决于LARGE_NUMBER是否真的很大。如果LARGE_NUMBER的大小为一个或两个缓存行,则您将不会注意到第一个和第二个版本之间的差异。但如果LARGE_NUMBER真的很大 - 你会的。但是,如果你的阵列比性能差异大得多,那么你肯定需要把它移到堆上。堆栈空间很昂贵,并且在其中分配兆字节的数据是错误的。
如果您的数组非常大,可以在堆上分配一次,并在迭代之间调用memset
。
答案 1 :(得分:2)
LARGE_NUMBER预计如何?
考虑到宽对象的堆栈分配可能比系统可以给线程的堆栈空间更宽,并且即使在性能开始之前,您可能面临“内存不足”问题。 (堆栈需要快速,因此不超过几兆字节:理想情况下它必须适合处理器缓存)
如果是这种情况,std :: vector(留在堆栈中,但管理堆中的分配)会更好。
但是在里面定义它会使它在每次迭代时被创建/销毁。现在:那些创造/破坏是否有意义(我的意思是:他们采取一些有意义的行动,每次都重复)或者你的问题只是在每次迭代时初始化为零?如果是这样的话,我可能会做类似的事情:
{ //just begin a scope block
std::vector<int> v(LARGE_NUMBER); //allocates LARGE_NUMBER int-s on heap
for (int i = 0; i <= LARGE_NUMBER; ++i)
{
std::fill(v.begin(), v.end(), 0); //reset at every iteration
// other stuff with v
}
} //here the vector and associated memory is finally eliminated
请注意,std:fill的性能与数组的初始化一样是线性的,但是你可以避免在每个周期分配/解除分配。
在任何情况下,根据定义,您的问题的复杂性为O 2 。
答案 2 :(得分:2)
取决于你的应用......我假设你有一个固定的数组大小?它将使用:http://www.cplusplus.com/reference/cstring/memset/
#include <stdio.h>
#include <string.h>
int* x = new int[LARGE_NUMBER];
for (int i = 0; i <= LARGE_NUMBER; ++i) {
memset(x,0,LARGE_NUMBER);
// do something with x
}
//some more stuff that needs x
delete[] x;
顺便说一句:我手头没有C / C ++来测试代码。