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

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

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

#include  #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  #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; } 

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

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

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

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

关于时间,第二个例子更好。 假设你在每个例子中对’foo’中的数组做的事情都是一样的。

在第二个示例中:您分配一个数组,并对其执行一些操作。 然后在你这样做之后摧毁它。

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

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

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

在for循环中声明数组会给我带来明确的代码味道 :它是一种缺乏模块性的解决方案。