当前位置:  开发笔记 > 编程语言 > 正文

使用成员函数指针与交换机的成本是多少?

如何解决《使用成员函数指针与交换机的成本是多少?》经验,为你挑选了2个好方法。

我有以下情况:

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
};

在我当前的实现中,我保存whichFoo构造函数中的数据成员的值,并使用switchin callFoo()来决定要调用哪个foo.或者,我可以switch在构造函数中使用a 来保存指向fooN()要调用的权限的指针callFoo().

我的问题是,如果A类的一个对象只构造一次,那么哪种方式更有效,而callFoo()被称为非常多次.所以在第一种情况下我们有多个switch语句的执行,而在第二种情况下只有一个开关,并且使用指向它的指针多次调用成员函数.我知道使用指针调用成员函数比直接调用它要慢.有人知道这个开销是多少还是少于一个switch

澄清:我意识到你从来没有真正知道哪种方法可以提供更好的性能,直到你尝试并计时.但是,在这种情况下,我已经实施了方法1,并且我想知道方法2是否可以至少在原则上更有效.它似乎可以,现在我有理由去实现它并尝试它.

哦,我也喜欢方法2更好的审美原因.我想我正在寻找实现它的理由.:)



1> Greg Hewgill..:

你是否确定通过指针调用成员函数比直接调用它更慢?你能衡量差异吗?

一般来说,在进行绩效评估时,不应该依赖自己的直觉.坐下来使用您的编译器和计时功能,并实际测量不同的选择.你可能会感到惊讶!

更多信息:有一篇优秀的文章成员函数指针和最快可能的C++代表,它们详细介绍了成员函数指针的实现.


指向虚拟成员函数的指针实际上可能是最一般情况下的结构,但指向常规成员函数的指针只是其地址.在简单的单继承情况下,指向虚拟成员函数的指针只需要是vtable的偏移量.

2> cos..:

你可以这样写:

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("<

实际函数指针的计算是线性和快速的:

  (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 

请注意,您甚至不必在构造函数中修复实际的函数编号.

我已将此代码与a生成的asm进行了比较switch.该switch版本不提供任何性能提升.

推荐阅读
重庆制造漫画社
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有