我有一些简单的功能
int f_0(int);
int f_1(int);
...
int f_n(int);
然后我有一些 for 循环,我在其中调用 f_i(),这个循环中的条件不必相同
for (int i = 0; i < n; i++) {
...
if (condition) {
int myInt = f_i(); // this is not real implementation but shows the result
// I want to achieve
... //edit
}
...
}
以下是我尝试实现的方法:
- 分解 for 循环并在相应部分调用每个函数。这会产生最快的代码,但这非常不雅,而且这样的代码很难进一步开发。
指向函数的指针
typedef int (*Foo) (int);
Foo fptr[] = { f_0, f_1, ... , f_n };
这是一种优雅的方法,但在我的情况下,它比打破循环慢 4.4。指向函数的常量指针产生类似的结果。
- 将我的功能封装成开关功能。这比打破循环慢 2.6。
有没有更好的方法来实现这一点?理想的解决方案是代码紧凑的解决方案,但编译器会分解循环并让计算速度最快。
我正在使用 MSVC 2012 并在发布模式下运行,优化设置为最大限度地提高速度。
编辑:
这是我的测试代码:
头文件
namespace c {
const int w = 1024;
const int A = w * w;
}
inline int f_0(int pos) { return (pos - c::w + c::A) % c::A; }
inline int f_1(int pos) { return (pos + 1 - c::w + c::A) % c::A; }
inline int f_2(int pos) { return (pos + 1) % c::A; }
inline int f_3(int pos) { return (pos + c::w) % c::A; }
inline int f_4(int pos) { return (pos - 1 + c::w) % c::A; }
inline int f_5(int pos) { return (pos - 1 + c::A) % c::A; }
typedef int (*NEIGH_F) (int);
typedef int (* const CNEIGH_F) (int);
const NEIGH_F fptr[] = { f_0, f_1, f_2, f_3, f_4, f_5 };
const CNEIGH_F cfptr[] = { f_0, f_1, f_2, f_3, f_4, f_5 };
inline int fswitch(int i, int pos) {
switch(i) {
case 0 : return f_0(pos); break;
case 1 : return f_1(pos); break;
case 2 : return f_2(pos); break;
case 3 : return f_3(pos); break;
case 4 : return f_4(pos); break;
case 5 : return f_5(pos); break;
default : return -1; break;
}
}
主文件
#include "head.h"
#include <iostream>
#include <time.h>
int main()
{
int maxRepeat = 100;
clock_t startTime = clock();
double sum = 0;
for (int repeat = 0; repeat < maxRepeat; repeat++)
for (int i = 0; i < c::A; i++) {
sum += f_0(i);
sum += f_1(i);
sum += f_2(i);
sum += f_3(i);
sum += f_4(i);
sum += f_5(i);
}
std::cout << "normal time: " << (clock() - startTime)/(double)CLOCKS_PER_SEC
<< " sum is: " << sum << std::endl;
startTime = clock();
sum = 0;
for (int repeat = 0; repeat < maxRepeat; repeat++)
for (int i = 0; i < c::A; i++) {
for (int j = 0; j < 6; j++)
sum += fptr[j](i);
}
std::cout << "pointer time: " << (clock() - startTime)/(double)CLOCKS_PER_SEC
<< " sum is: " << sum << std::endl;
startTime = clock();
sum = 0;
for (int repeat = 0; repeat < maxRepeat; repeat++)
for (int i = 0; i < c::A; i++) {
for (int j = 0; j < 6; j++)
sum += cfptr[j](i);
}
std::cout << "const pointer time: " << (clock() - startTime)/(double)CLOCKS_PER_SEC
<< " sum is: " << sum << std::endl;
startTime = clock();
sum = 0;
for (int repeat = 0; repeat < maxRepeat; repeat++)
for (int i = 0; i < c::A; i++) {
for (int j = 0; j < 6; j++)
sum += fswitch(j, i);
}
std::cout << "switch time: " << (clock() - startTime)/(double)CLOCKS_PER_SEC
<< " sum is: " << sum << std::endl;
std::cin.ignore();
return 0;
}
函数 f_i 是我在实际实现中使用的函数,但是由于实际实现中的测试目的,这里的循环要简单得多,问题的第二个代码片段中显示了几种不同的形式循环。
编辑2:
我的循环形式应该保持不变我只是想找到如何将 f_i 放入我的循环的最佳方法。