【问题标题】:Generic vs Overloading in terms of execution speed执行速度方面的通用与重载
【发布时间】:2021-04-20 10:44:42
【问题描述】:

我试图找出在使用泛型编程概念而不是重载时执行速度如何延迟。 这是我的代码。

重载

class Addition{
public:
    int sum (int a, int b){
        return a+b;
    }

    double sum (double a, double b){
        return a+b;
    }
};

int main(){
    Addition a;
    cout<<a.sum(5,6)<<endl;
    cout<<a.sum(5.1,6.2)<<endl;
    return 0;
}

通用

template <class T>
class Addition{
public:
    T sum(T a,T b){
        return a+b;
    }
};

int main(){
    Addition <int>a;
    Addition <double>b;
    cout<<a.sum(5,6)<<endl;
    cout<<b.sum(5.1,6.2);
    return 0;
}

我发现通用概念更有效,但我想知道为什么? 更新:由于@user15388024 提到的缺少 endl,Generic 被认为更有效

【问题讨论】:

  • 是什么让您得出结论认为一个比另一个更有效率?
  • 关于效率的声明需要更多的东西才有意义。什么编译器,什么编译器设置,你是如何测量的,在什么机器上?没有这些信息,说“A 比 B 更有效”毫无意义
  • 此代码中关于intdouble 上的函数的任何选择都是在编译时完成的。我认为没有运行时差异。如果您认为有,请测量它。
  • 我用quick-bench.com/q/OdgFIOROlvUVzajZkaa5hemVupQ 对您的代码进行了基准测试,不同之处在于您的第二个代码中缺少&lt;&lt;endl。添加后,基准是相等的:quick-bench.com/q/vCxh4G8acvEAR2IWisU-gFbZdE0'\n' 替换endl 会稍微提高性能:quick-bench.com/q/GsNKlf5k2ZK3r8n6RHy68USWvdg
  • 编译器将使用您的模板类为使用的每种模板类型生成类实例化,因此在这种情况下永远不会有性能差异。

标签: c++ generics overloading


【解决方案1】:

我使用 https://quick-bench.com/q/OdgFIOROlvUVzajZkaa5hemVupQ 对您的代码进行了基准测试

#include <iostream>
class Addition1{
public:
    int sum (int a, int b){
        return a+b;
    }

    double sum (double a, double b){
        return a+b;
    }
};

template <class T>
class Addition2{
public:
    T sum(T a,T b){
        return a+b;
    }
};

static void Overloading(benchmark::State& state) {
  // Code inside this loop is measured repeatedly
  for (auto _ : state) {
    Addition1 a;
    std::cout<<a.sum(5,6)<<std::endl;
    std::cout<<a.sum(5.1,6.2)<<std::endl;

    benchmark::DoNotOptimize(a);
  }
}
// Register the function as a benchmark
BENCHMARK(Overloading);

static void Generic(benchmark::State& state) {
  // Code before the loop is not measured
  for (auto _ : state) {
    Addition2 <int>a;
    Addition2 <double>b;
    std::cout<<a.sum(5,6)<<std::endl;
    std::cout<<b.sum(5.1,6.2);

    benchmark::DoNotOptimize(a);
    benchmark::DoNotOptimize(b);
  }
}
BENCHMARK(Generic);

不同之处在于您的第二个代码中缺少 &lt;&lt;endl

在我添加它之后,基准是相等的:https://quick-bench.com/q/vCxh4G8acvEAR2IWisU-gFbZdE0

#include <iostream>
class Addition1{
public:
    int sum (int a, int b){
        return a+b;
    }

    double sum (double a, double b){
        return a+b;
    }
};

template <class T>
class Addition2{
public:
    T sum(T a,T b){
        return a+b;
    }
};

static void Overloading(benchmark::State& state) {
  // Code inside this loop is measured repeatedly
  for (auto _ : state) {
    Addition1 a;
    std::cout<<a.sum(5,6)<<std::endl;
    std::cout<<a.sum(5.1,6.2)<<std::endl;

    benchmark::DoNotOptimize(a);
  }
}
// Register the function as a benchmark
BENCHMARK(Overloading);

static void Generic(benchmark::State& state) {
  // Code before the loop is not measured
  for (auto _ : state) {
    Addition2 <int>a;
    Addition2 <double>b;
    std::cout<<a.sum(5,6)<<std::endl;
    std::cout<<b.sum(5.1,6.2)<<std::endl;

    benchmark::DoNotOptimize(a);
    benchmark::DoNotOptimize(b);
  }
}
BENCHMARK(Generic);

endl 替换为'\n' 会稍微提高性能: https://quick-bench.com/q/GsNKlf5k2ZK3r8n6RHy68USWvdg

#include <iostream>
class Addition1{
public:
    int sum (int a, int b){
        return a+b;
    }

    double sum (double a, double b){
        return a+b;
    }
};

template <class T>
class Addition2{
public:
    T sum(T a,T b){
        return a+b;
    }
};

static void Overloading(benchmark::State& state) {
  // Code inside this loop is measured repeatedly
  for (auto _ : state) {
    Addition1 a;
    std::cout<<a.sum(5,6)<<'\n';
    std::cout<<a.sum(5.1,6.2)<<'\n';

    benchmark::DoNotOptimize(a);
  }
}
// Register the function as a benchmark
BENCHMARK(Overloading);

static void OverloadingEndl(benchmark::State& state) {
  // Code inside this loop is measured repeatedly
  for (auto _ : state) {
    Addition1 a;
    std::cout<<a.sum(5,6)<<std::endl;
    std::cout<<a.sum(5.1,6.2)<<std::endl;

    benchmark::DoNotOptimize(a);
  }
}
// Register the function as a benchmark
BENCHMARK(OverloadingEndl);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-28
    • 1970-01-01
    • 1970-01-01
    • 2013-08-10
    • 2013-06-02
    • 2013-04-15
    相关资源
    最近更新 更多