编译时间与运行时递归

时间:2015-10-25 00:58:53

标签: c++ templates recursion

模板递归比非模板递归更有效吗?

即。两者中哪一个更好:

"

2 个答案:

答案 0 :(得分:1)

如果模板版本速度慢,我会感到惊讶。它应该在大多数时间更快,如果不是每次都。毕竟,模板版本在编译时计算值。

这是两个方法的时间计划。

#include <iostream>
#include <cstddef>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <cassert>

typedef std::vector<int> Ivec;

template <int N>
void test1(Ivec& v){
   assert(v.size() >= N);
   for (int i=0;i<N;i++){v[i]++;}
   test1<N-1>(v);
}

template <>
void test1<0>(Ivec& v){}

void test2(Ivec& v,int N){
   assert(v.size() >= N);
   for (int i=0;i<N;i++){v[i]++;}
   if (N == 1) {return;}
   test2(v,N-1);
}

void timeFunction(void (*fun)())
{
   clock_t start = std::clock();
   fun();
   clock_t end = std::clock();
   double secs = 1.0*(end-start)/CLOCKS_PER_SEC;
   std::cout << "Time taken: " << secs << std::endl;
}

void time_test1()
{
   Ivec a;
   const int N = 500;
   for (int i = 0; i < N; ++i )
   {
      a.push_back(std::rand());
   }

   for ( int i = 0; i < N*20; ++i )
   {
      test1<N>(a);
   }
}

void time_test2()
{
   Ivec a;
   const int N = 500;
   for (int i = 0; i < N; ++i )
   {
      a.push_back(std::rand());
   }

   for ( int i = 0; i < N*20; ++i )
   {
      test2(a, N);
   }
}


int main()
{
   std::srand(time(NULL));
   timeFunction(time_test1);
   timeFunction(time_test2);
   return 0;
}

程序在带有g ++版本4.8.4的Linux机器上构建,命令为:

g++ -Wall -std=c++11     socc.cc   -o socc

输出:

Time taken: 3.96467
Time taken: 4.32788

输出验证了我的预感。像往常一样,您的里程可能会有所不同。

答案 1 :(得分:0)

模板递归应该更快,但是你需要在编译时知道N.

哪个更好?

通常是函数递归,因为它更灵活,只生成一次机器代码。

但是如果你在编译时知道N(作为例子定义)而不是你从文件中读取的东西,并且性能需求大于生成代码的大小,那么你可以优先考虑优化编译器可以做的。