1

代码如下所示:

for (int i = 0; i <= LARGE_NUMBER; ++i) {
    int x[LARGE_NUMBER] = {0};
    // do something with x
}

我认为x每次for-loopwades thru时都会创建数组0~LARGE_NUMBER,所以这会影响性能吗?会-O2有所帮助吗?

4

3 回答 3

2

您的数组将在每次迭代中归零,所以肯定会。

这段代码是线性时间,数组的每个元素都将被初始化为零:

int x[LARGE_NUMBER] = {0};

这是一个常数时间,只是堆栈指针的增量:

int x[LARGE_NUMBER];

性能将取决于 LARGE_NUMBER 是否真的很大。如果 LARGE_NUMBER 的大小为一个或两个缓存行,那么您不会注意到第一个版本和第二个版本之间的差异。但如果 LARGE_NUMBER 真的很大 - 你会的。但是,如果您的数组比性能差异大得多,那么您肯定需要将其移动到堆中。堆栈空间很昂贵,并且在其中分配兆字节的数据是错误的。

如果您的数组真的很大,您可以在堆上分配一次并memset在迭代之间调用。

于 2013-02-25T07:21:11.057 回答
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复杂性。

于 2013-02-25T07:35:30.193 回答
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++ 来测试代码。

于 2013-02-25T07:58:12.147 回答