C中循环中内存分配的代价

时间:2015-03-07 20:12:48

标签: c allocation

在时间成本方面,在循环内部或外部分配数组之间是否存在显着差异?

我在程序循环中的函数中使用了很多数组,我是否应该将所有数组作为函数参数传递以提高性能,尽管它会降低可读性?例如:

#include <stdlib.h>
#define N 1000000
void foo()
{
    int* array = (int*)malloc(N*sizeof(int));
    /*
    Do something with the array
    */
    free(array);
}
int main()
{
    int i;
    for(i=0; i<1000000; i++)
        foo();
    return 0;
}

#include <stdlib.h>
#define N 1000000
void foo(int* array)
{
    /*
    Do something with the array
    */
}
int main()
{
    int i;
    int* array = (int*)malloc(N*sizeof(int));
    for(i=0; i<1000000; i++)
        foo(array);
    free(array);
    return 0;
}

3 个答案:

答案 0 :(得分:2)

关于时间,第二个例子更好。假设你将使用数组在foo&#39;每个例子都是一样的。

在第二个例子中:你分配一个数组,并多次做一些事情。然后在你这样做之后摧毁它。

在第一个例子中:循环的每次迭代都会创建一个新数组,执行某些操作然后销毁它。这意味着每次循环迭代都需要额外的时间来创建和销毁数组。

答案 1 :(得分:2)

内存分配的成本并不十分依赖于分配的大小。粗略地说,任何大小的内存分配都是O(1),显然标准库已经过优化,可以尽可能快地进行分配。

因此,如果你需要一个非常大的分配,就像在示例程序中一样,分配的成本与初始化分配的内存的成本相比是微不足道的(更不用说实际进行计算的成本了) 。

对于非常紧密的循环中的小分配,其中分配开销可能是显而易见的,替代机制可能是有用的;其中一个是问题中建议的,将预分配的数组作为附加参数传递给函数。 (其他可能性包括使用C&#39的可变长度数组(VLA),如果它们在所有目标平台上可用,或alloca / _alloca / _malloca。)

但我建议不要实施这种形式的微观优化,直到有确凿的证据证明节省时间是合理的;否则,可维护性和可读性的成本将超过您可能实现的任何小的时间节省。

答案 2 :(得分:1)

声明数组然后使用它会让我感觉更好。

您的声明发生在更高级别的代码体中并且发生一次:因此很容易理解发生了什么,更改分配大小,处理分配错误和调试。

在for循环中声明数组为我提出了一个明确的code smell:这是一个缺乏模块性的解决方案。