Dim*_*ima 12 c++ function-pointers
我有以下情况:
class A
{
public:
A(int whichFoo);
int foo1();
int foo2();
int foo3();
int callFoo(); // cals one of the foo's depending on the value of whichFoo
};
Run Code Online (Sandbox Code Playgroud)
在我当前的实现中,我保存whichFoo构造函数中的数据成员的值,并使用switchin callFoo()来决定要调用哪个foo.或者,我可以switch在构造函数中使用a 来保存指向fooN()要调用的权限的指针callFoo().
我的问题是,如果A类的一个对象只构造一次,那么哪种方式更有效,而callFoo()被称为非常多次.所以在第一种情况下我们有多个switch语句的执行,而在第二种情况下只有一个开关,并且使用指向它的指针多次调用成员函数.我知道使用指针调用成员函数比直接调用它要慢.有人知道这个开销是多少还是少于一个switch?
澄清:我意识到你从来没有真正知道哪种方法可以提供更好的性能,直到你尝试并计时.但是,在这种情况下,我已经实施了方法1,并且我想知道方法2是否可以至少在原则上更有效.它似乎可以,现在我有理由去实现它并尝试它.
哦,我也喜欢方法2更好的审美原因.我想我正在寻找实现它的理由.:)
Gre*_*ill 11
你是否确定通过指针调用成员函数比直接调用它更慢?你能衡量差异吗?
一般来说,在进行绩效评估时,不应该依赖自己的直觉.坐下来使用您的编译器和计时功能,并实际测量不同的选择.你可能会感到惊讶!
更多信息:有一篇优秀的文章成员函数指针和最快可能的C++代表,它们详细介绍了成员函数指针的实现.
你可以这样写:
class Foo {
public:
Foo() {
calls[0] = &Foo::call0;
calls[1] = &Foo::call1;
calls[2] = &Foo::call2;
calls[3] = &Foo::call3;
}
void call(int number, int arg) {
assert(number < 4);
(this->*(calls[number]))(arg);
}
void call0(int arg) {
cout<<"call0("<<arg<<")\n";
}
void call1(int arg) {
cout<<"call1("<<arg<<")\n";
}
void call2(int arg) {
cout<<"call2("<<arg<<")\n";
}
void call3(int arg) {
cout<<"call3("<<arg<<")\n";
}
private:
FooCall calls[4];
};
Run Code Online (Sandbox Code Playgroud)
实际函数指针的计算是线性和快速的:
(this->*(calls[number]))(arg);
004142E7 mov esi,esp
004142E9 mov eax,dword ptr [arg]
004142EC push eax
004142ED mov edx,dword ptr [number]
004142F0 mov eax,dword ptr [this]
004142F3 mov ecx,dword ptr [this]
004142F6 mov edx,dword ptr [eax+edx*4]
004142F9 call edx
Run Code Online (Sandbox Code Playgroud)
请注意,您甚至不必在构造函数中修复实际的函数编号.
我已将此代码与a生成的asm进行了比较switch.该switch版本不提供任何性能提升.
| 归档时间: |
|
| 查看次数: |
5253 次 |
| 最近记录: |