我了解了静态多态性和运行时多态性之间的区别,从那时起我就读了很多关于它的东西。另外,因为我发现实现了一个静态多态接口(以一种方式,一个类可以使用具有基类定义的对象,而不知道该对象是用什么“派生”类实例化的)。
所以我跑了一个小测试来比较这些不同的实现。
这是代码:
#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 编译。
我的问题是:为什么模板实现最慢?真的是因为编译器的优化吗?如果是,它们是什么,我怎样才能改变我的测试以获得“真正的”运行时间?如果没有,我做错了什么?