1

我了解了静态多态性和运行时多态性之间的区别,从那时起我就读了很多关于它的东西。另外,因为我发现实现了一个静态多态接口(以一种方式,一个类可以使用具有基类定义的对象,而不知道该对象是用什么“派生”类实例化的)。

所以我跑了一个小测试来比较这些不同的实现。

这是代码:

#include <functional>
#include <iostream>
#include <ctime>
#include <chrono>
#include <memory>

class BaseLambda
{
    public:
        double run(double param){return m_func(param);};
    protected:
        BaseLambda(std::function<double(double)> func) : m_func(func) {  };
        std::function<double(double)> m_func;
};

class DerivedLambda : public BaseLambda
{
    public:
        DerivedLambda() : BaseLambda([](double param){return DerivedLambda::runImpl(param);}) {  };
    private:
        static double runImpl(double param) {return (param * param) / 2.5;};
};

class BaseVirtual
{
    public:
        double run(double param){return runImpl(param);};
    protected:
        virtual double runImpl(double param) = 0;
};

class DerivedVirtual : public BaseVirtual
{
    protected:
        double runImpl(double param) {return (param * param) / 2.5;};
};


template<class C> class BaseTemplate
{
    public:
        double run(double param){return static_cast<C*>(this)->runImpl(param);};
};

class DerivedTemplate : public BaseTemplate<DerivedTemplate>
{
    public:
        double runImpl(double param) {return (param * param) / 2.5;};
};


int main()
{
    std::clock_t  c_start = std::clock();

    std::unique_ptr<BaseVirtual> baseVirtual = std::make_unique<DerivedVirtual>();
    for(unsigned int i = 0 ; i < 1000000 ; ++i) {
        auto var = baseVirtual->run(10.6);
    }
    baseVirtual.reset(nullptr);

    std::clock_t  c_end = std::clock();

    std::cout << "Execution time with virtual : "
        << 1000.0 * (c_end-c_start) / CLOCKS_PER_SEC << " ms" << std::endl;


    c_start = std::clock();

    std::unique_ptr<BaseLambda> baseLambda = std::make_unique<DerivedLambda>();
    for(unsigned int i = 0 ; i < 1000000 ; ++i) {
        auto var = baseLambda->run(10.6);
    }
    baseLambda.reset(nullptr);

    c_end = std::clock();

    std::cout << "Execution time with lambda : "
        << 1000.0 * (c_end-c_start) / CLOCKS_PER_SEC << " ms" << std::endl;


    std::unique_ptr<BaseTemplate<DerivedTemplate>> baseTemplate = std::make_unique<DerivedTemplate>();
    for(unsigned int i = 0 ; i < 1000000 ; ++i) {
        auto var = baseTemplate->run(10.6);
    }
    baseTemplate.reset(nullptr);

    c_end = std::clock();

    std::cout << "Execution time with template : "
        << 1000.0 * (c_end-c_start) / CLOCKS_PER_SEC << " ms" << std::endl;
}

问题是,当我运行它时,虚拟实现是最快的,而静态多态应该更快。下面是一个执行结果示例:

虚拟执行时间:53 ms
lambda 执行时间:94 ms
模板执行时间:162 ms

我猜这是因为一些编译器优化。我用 gcc 6.3.0 编译。

我的问题是:为什么模板实现最慢?真的是因为编译器的优化吗?如果是,它们是什么,我怎样才能改变我的测试以获得“真正的”运行时间?如果没有,我做错了什么?

4

0 回答 0