【问题标题】:calling base class method from polymorphic base pointer is slow从多态基指针调用基类方法很慢
【发布时间】:2017-01-31 19:34:05
【问题描述】:

标题很混乱.. 这是一个总结它的最小代码 -

#include <iostream>
#include <chrono>
#include <memory>

using namespace std;
using namespace std::chrono;

enum class TYPE {base, child};

class Base {
    int n;
  protected: Base(int _n) : n(_n) {}
  public: virtual TYPE getType(){ return TYPE::base; }
};

class Child: public Base {
    int m;
  public:
    TYPE getType(){ return TYPE::child; }
    Child(int _n, int _m) : Base(_n), m(_m) {}
};

int main() {
    unique_ptr<Base> b = make_unique<Child>(6, 7);
    TYPE tB = TYPE::base;
    TYPE tC = TYPE::child;

    {
        auto t1 = high_resolution_clock::now();

        std::cout << (tB == b->Base::getType()) << ", ";

        auto t2 = high_resolution_clock::now();
        auto duration = duration_cast<microseconds>( t2 - t1 ).count();
        cout << "Duration: " << duration << std::endl;

    }

    {
        auto t1 = high_resolution_clock::now();

        std::cout << (tC == b->getType()) << ", ";

        auto t2 = high_resolution_clock::now();
        auto duration = duration_cast<microseconds>( t2 - t1 ).count();
        cout << "Duration: " << duration << std::endl;

    }

    return 0;
}

并且输出如下 -

1, Duration: 12  // first run was 62
1, Duration: 0

我知道虚函数与普通(compileTime-resolved)函数相比可能会慢一点,但是为什么上面的函数 - b-&gt;Base::getType() 比虚方法 - b-&gt;getType() 慢?它是否进行了两次旅行,例如虚拟解决功能然后返回基类?谁能帮我理解这一点?

IDEONE


嗯,稍微修改代码以包含循环,结果很清楚 - IDEONE

1, Duration: 33
1, Duration: 1478051

【问题讨论】:

  • 需要更多运行来测量平均执行时间,运行一次根本不够。
  • @iksemyonov 我已经测量了它们并如上所述。第一次运行是 62 而不是 12,随后的运行是 ~8-12。然而,提供的代码并没有这样做,因为它是一个最小的例子。
  • 我的意思是,您应该在一个循环中运行几百或几千次调用,然后根据该数据比较一次函数调用的平均时间。当前的方法是设置此实验的错误方法。
  • @iksemyonov 嗯,我正在多次运行可执行文件,而不是在同一个可执行文件中执行多个函数类。桌子已经转了,这很尴尬:p
  • 你的一个函数调用的计时数字被调用 cout 所用的时间所淹没。最初的 cout 调用可能正在为缓冲区分配内存,并且会花费更长的时间。第一次调用 (b-&gt;Base::getType()) 不会是虚拟的,甚至可能是内联的。

标签: c++ class oop c++11 polymorphism


【解决方案1】:

调用cout 所用的时间超出了您的一个函数调用的计时数字。最初的cout 调用可能正在为缓冲区分配内存,并且会花费更长的时间。

第一次调用 (b-&gt;Base::getType()) 不会是虚拟的,甚至可以内联。

【讨论】:

    猜你喜欢
    • 2014-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多