通常有太多因素在起作用......并且很容易证明这两种方式:
例如,分割以下循环会导致速度几乎减慢 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秒