在时间成本方面,在循环内部或外部分配数组之间是否存在显着差异?
我在程序循环中的函数中使用了很多数组,我是否应该将所有数组作为函数参数传递以提高性能,尽管它会降低可读性?例如:
#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;
}
答案 0 :(得分:2)
关于时间,第二个例子更好。假设你将使用数组在foo&#39;每个例子都是一样的。
在第二个例子中:你分配一个数组,并多次做一些事情。然后在你这样做之后摧毁它。
在第一个例子中:循环的每次迭代都会创建一个新数组,执行某些操作然后销毁它。这意味着每次循环迭代都需要额外的时间来创建和销毁数组。
答案 1 :(得分:2)
内存分配的成本并不十分依赖于分配的大小。粗略地说,任何大小的内存分配都是O(1),显然标准库已经过优化,可以尽可能快地进行分配。
因此,如果你需要一个非常大的分配,就像在示例程序中一样,分配的成本与初始化分配的内存的成本相比是微不足道的(更不用说实际进行计算的成本了) 。
对于非常紧密的循环中的小分配,其中分配开销可能是显而易见的,替代机制可能是有用的;其中一个是问题中建议的,将预分配的数组作为附加参数传递给函数。 (其他可能性包括使用C&#39的可变长度数组(VLA),如果它们在所有目标平台上可用,或alloca
/ _alloca
/ _malloca
。)
但我建议不要实施这种形式的微观优化,直到有确凿的证据证明节省时间是合理的;否则,可维护性和可读性的成本将超过您可能实现的任何小的时间节省。
答案 2 :(得分:1)
声明数组然后使用它会让我感觉更好。
您的声明发生在更高级别的代码体中并且发生一次:因此很容易理解发生了什么,更改分配大小,处理分配错误和调试。
在for循环中声明数组为我提出了一个明确的code smell:这是一个缺乏模块性的解决方案。