通常有太多因素在起作用......而且很容易证明两种方式:
例如,拆分以下循环会导致几乎 2 倍的减速(底部有完整的测试代码):
for (int c = 0; c < size; c++){
data[c] *= 10;
data[c] += 7;
data[c] &= 15;
}
这几乎是显而易见的,因为您需要循环 3 次而不是一次,并且您需要 3 次遍历整个数组而不是 1 次。
另一方面,如果你看一下这个问题:为什么在单独的循环中元素加法比在组合循环中快得多?
for(int j=0;j<n;j++){
a1[j] += b1[j];
c1[j] += d1[j];
}
由于内存对齐,有时情况正好相反。
从中可以得到什么?
几乎任何事情都可能发生。两种方法都不是更快,它在很大程度上取决于循环内的内容。
因此,确定这种优化是否会提高性能通常需要反复试验。有了足够的经验,您就可以做出相当自信(受过教育)的猜测。但总的来说,期待任何事情。
“每个额外的 for 循环将花费相当于两个 int 分配的成本。”
你说得对,事情没那么简单。事实上,它是如此复杂,以至于这些数字并没有多大意义。由于无序执行和数据依赖性等多种因素,循环迭代在一种情况下可能需要 X 个周期,但在另一种情况下需要 Y 个周期。
性能不仅取决于上下文,而且还因不同的处理器而异。
这是测试代码:
#include <time.h>
#include <iostream>
using namespace std;
int main(){
int size = 10000;
int *data = new int[size];
clock_t start = clock();
for (int i = 0; i < 1000000; i++){
#ifdef TOGETHER
for (int c = 0; c < size; c++){
data[c] *= 10;
data[c] += 7;
data[c] &= 15;
}
#else
for (int c = 0; c < size; c++){
data[c] *= 10;
}
for (int c = 0; c < size; c++){
data[c] += 7;
}
for (int c = 0; c < size; c++){
data[c] &= 15;
}
#endif
}
clock_t end = clock();
cout << (double)(end - start) / CLOCKS_PER_SEC << endl;
system("pause");
}
输出(一个循环): 4.08 秒
输出(3 个循环): 7.17 秒