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

加速gcc中的虚函数调用

如何解决《加速gcc中的虚函数调用》经验,为你挑选了4个好方法。

使用gprof分析我的C++代码,我发现我的大部分时间花在一遍又一遍地调用一个虚拟方法上.该方法本身很短,如果它不是虚拟的,可能会内联.

有什么方法可以加快这一点,而不是将其重写为不是虚拟的?



1> Andrew Grant..:

你确定时间与呼叫有关吗?可能是成本本身的功能吗?如果是这种情况,简单地内联可能会使您的分析器中的功能消失,但您不会看到太多的加速.

假设真的是进行如此多虚拟调用的开销,那么在不使虚拟非事物的情况下你可以做的事情是有限的.

如果呼叫有时间/标志之类的早期出现,那么我将经常使用两级方法.检查内联非虚拟调用,只有在必要时才调用特定于类的行为.

例如

class Foo
{
public:

inline void update( void )
{
  if (can_early_out)
    return;

  updateImpl();
}

protected:

virtual void updateImpl( void ) = 0;    
}; 



2> Charlie Mart..:

是时候花在实际的函数调用中,还是在函数本身中?

虚拟函数调用明显比非虚拟调用慢,因为虚拟呼叫需要额外的解引用.(谷歌为'vtable',如果你想阅读所有毛茸茸的细节.)更新:事实证明维基百科的文章并不坏.

但是,"明显地"在这里意味着一些指令如果它消耗了总计算的很大一部分,包括在被调用函数中花费的时间,那么这听起来像是一个考虑非虚拟化和内联的奇妙场所.

但是在近20年的C++中,我认为我从未见过这种情况真的发生过.我很想看到代码.



3> DaClown..:

如果虚拟呼叫确实是瓶颈,请试试CRTP.



4> j_random_hac..:

请注意,"虚拟"和"内联"并不是对立的 - 方法可以是两者.如果编译器可以在编译时确定对象的类型,编译器将很乐意内联虚函数:

struct B {
    virtual int f() { return 42; }
};

struct D : public B {
    virtual int f() { return 43; }
};

int main(int argc, char **argv) {
    B b;
    cout << b.f() << endl;   // This call will be inlined

    D d;
    cout << d.f() << endl;   // This call will be inlined

    B& rb = rand() ? b : d;
    cout << rb.f() << endl;  // Must use virtual dispatch (i.e. NOT inlined)
    return 0;
}

[更新:rb在编译时无法识别某些真正的动态对象类型 - 感谢MSalters]

如果可以在编译时确定对象的类型但是函数不可内联(例如,它很大或在类定义之外定义),则将非虚拟地调用它.

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