首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >虚函数实现

虚函数实现
EN

Stack Overflow用户
提问于 2010-03-09 09:29:47
回答 8查看 1.8K关注 0票数 2

我一直在听这句话。Switch..Case对于代码维护是有害的,但它提供了更好的性能(因为编译器可以内联东西等)。虚函数非常适合代码维护,但它们会导致两个指针间接的性能损失。

假设我有一个基类,包含两个子类(X和Y)和一个虚拟函数,因此将有两个虚拟表。该对象有一个指针,它将根据该指针选择一个虚拟表。所以对于编译器来说,它更像是

代码语言:javascript
复制
switch( object's function ptr )
{

   case 0x....:

       X->call();

       break;

   case 0x....:

       Y->call();
};

既然编译器可以在这里做同样的内联和其他事情,那么为什么虚函数的成本会更高,如果它可以这样实现的话。或者解释一下,为什么决定不以这种方式实现虚函数执行?

谢谢,Gokul。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2010-03-09 09:40:03

由于独立的编译模型,编译器无法做到这一点。

在编译虚函数调用时,编译器无法确定有多少不同的子类。

考虑下面的代码:

代码语言:javascript
复制
// base.h
class base
{
public:
    virtual void doit();
};

还有这个:

代码语言:javascript
复制
// usebase.cpp
#include "base.h"

void foo(base &b)
{
    b.doit();
}

当编译器在foo中生成虚拟调用时,它不知道基类的哪些子类将在运行时存在。

票数 2
EN

Stack Overflow用户

发布于 2010-03-09 10:03:00

您的问题基于对交换机和虚拟函数工作方式的误解。我将给出几个要点,而不是用一篇关于代码生成的长篇论文来填满这个方框:

  • Switch语句不一定比虚函数调用更快,也不一定是内联的。您可以了解有关将switch语句转换为汇编herehere的方法的更多信息。
  • 虚函数调用速度慢的不是指针查找,而是间接分支。对于complicated reasons having to do with the internal electronics of the CPU,对于大多数现代处理器,执行“直接分支”比执行"indirect branch“更快,”直接分支“是在指令中编码目标地址的,而”直接分支“是在运行时计算地址的。虚函数调用和大的switch语句通常被实现为间接分支。
  • 在上面的例子中,switch是完全冗余的。一旦计算出对象的成员函数指针,CPU就可以直接分支到该对象。即使链接器知道可执行文件中存在的每个可能的成员对象,仍然没有必要添加表查找。
票数 1
EN

Stack Overflow用户

发布于 2010-03-09 12:17:25

以下是一些具体测试的结果。这些特定的结果来自VC++ 9.0/x64:

代码语言:javascript
复制
Test Description: Time to test a global using a 10-way if/else if statement
CPU Time:        7.70  nanoseconds           plus or minus      0.385

Test Description: Time to test a global using a 10-way switch statement
CPU Time:        2.00  nanoseconds           plus or minus     0.0999

Test Description: Time to test a global using a 10-way sparse switch statement
CPU Time:        3.41  nanoseconds           plus or minus      0.171

Test Description: Time to test a global using a 10-way virtual function class
CPU Time:        2.20  nanoseconds           plus or minus      0.110

在稀疏情况下,switch语句的速度要慢得多。在密集的情况下,switch语句可能会更快,但switch和虚拟函数分派会有一些重叠,因此,虽然switch可能更快,但差距很小,我们甚至不能确定它是否更快,更不用说足够快了。如果switch语句中的情况是稀疏的,那么虚函数调用将会更快这一点是毫无疑问的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2406060

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档