我有一个class transition
,里面有一个成员函数rate
。我要求一种方法,允许我在创建这些时刻之后将自定义设计的rate
插入transition
的时刻,并且在运行时会很快!
我想优化代码以提高速度。 rate
进行简单的计算,但是程序经常调用很多次。所以我想我应该避免使用虚函数...问题:在C ++(模板,boost,......)中实现这一目标的其他最佳方法是什么?关于特定方法的速度的评论将不胜感激。谢谢!
class transition {
public:
transition() : vec() {}
double rate(T_vec::iterator a) { return ...; }
private:
T_vec vec;
};
/* custom rate #1 */
double my_rate_1( T_vec::iterator) {
/* do something */
return ans;
}
/* custom rate #2 */
double my_rate_2( T_vec::iterator) {
/* do something */
return ans;
}
const int N=10;
int main (void) {
vector<transition*> ts(N);
for(int i=0;i!=N;++i) ts[i] = new transition;
/* How to efficiently implement the pseudo code that follows? */
ts[0]->rate = my_rate_1;
ts[1]->rate = my_rate_2;
/* ... */
}
答案 0 :(得分:3)
至少有三种方法可以实现这一点。
选项1是虚拟方法。您无法在创建实例后绑定方法,但在创建之后,您可以将所有派生类视为transition
。
class transition {
...
virtual double rate(T_vec::iterator a) = 0;
};
class my_transition_1 : public transition {
...
double rate(T_vec::iterator a) { ... }
};
class my_transition_2 : public transition {
...
double rate(T_vec::iterator a) { ... }
};
选项2是回调。您可以在创建对象后在运行时更改方法。这是最有活力的。在这种情况下,它的开销略高,因为迭代器有一个额外的复制结构,编译器更难以优化间接调用。
class transition {
public:
....
typedef double (*RateFunction)(T_vec::iterator a);
void set_rate(RateFunction r) { _fun = r; }
double rate(T_vec::iterator a) { return (*_fun)(a); }
private:
RateFunction _fun;
};
double my_rate_1(T_vec::iterator a) {
...
}
...
transition t;
t.set_rate(my_rate_1);
选项3是仿函数模板。您必须在构造时指定所有内容,但这样可以避免间接调用并具有最佳性能。
template <typename Rate>
class transition {
double rate(T_vec::iterator a) {
return Rate()(a);
}
};
class my_rate_1 {
double operator()(T_vec::iterator a) {
....
}
};
class my_rate_2 {
double operator()(T_vec::iterator a) {
....
}
};
transition<my_rate_1> t1;
transition<my_rate_2> t2;
选项4不可扩展,但您可以避免间接函数调用,并有机会在创建对象后设置速率。
class transition {
public:
enum RateCode {
RATE_1,
RATE_2,
...
}
double rate(T_vec::iterator i) {
switch (_rate_code) {
case RATE_1: {
...
return result;
}
case RATE_2: {
...
return result;
}
default:
assert(false);
}
}
void setRate(RateCode r) { _rate_code = r; }
private:
RateCode _rate_code;
}
答案 1 :(得分:1)
如果要绑定到任意函数,请查看FastDelegate文章。还有article of a more portable implementation代表的想法。
如果您可以安排代码以便在编译时知道特定实例,那么假设编译器完成其工作,这将更快。它更快的原因是真正的委托意味着对函数指针的调用,并且打破了当今CPU中的推测性执行和流水线操作。
您可能还想阅读C ++ 11。在C ++ 11中,lambda函数(可以传递的内联函数)是一个重要的扩展,我希望编译器能够努力优化它们。