
#include <chrono>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <vector>
 
typedef unsigned long long Integer;

struct Functor
{
   void operator()(Integer i, Integer &sum) const
   {
      sum += std::rand();
      if ( i > 0 )
      {
         this->operator()(i - 1, sum);
      }
   }
};

void recurse(Integer i, Integer& sum)
{
   sum += std::rand();
   if ( i > 0 )
   {
      recurse(i - 1, sum);
   }
}
 
int main()
{
   const Integer n(50ull * 1000ull * 1000ull);
   const auto t_0(std::chrono::high_resolution_clock::now());
   Integer functor_sum(0);
   Functor functor;
   functor(n, functor_sum);
   const auto t_1(std::chrono::high_resolution_clock::now());
   Integer sum(0);
   recurse(n, sum);
   const auto t_2(std::chrono::high_resolution_clock::now());
   std::function<void(Integer, Integer&)> lambda_recurse([&lambda_recurse](Integer i, Integer& l_sum)
   {
      l_sum += std::rand();
      if ( i > 0 )
      {
         lambda_recurse(i - 1, l_sum);
      }
   });
   Integer lambda_sum(0);
   lambda_recurse(n, lambda_sum);
   const auto t_3(std::chrono::high_resolution_clock::now());
   std::cout << "functor: " << std::chrono::duration_cast<std::chrono::milliseconds>(t_1 - t_0).count() << "\n";
   std::cout << "plain: " << std::chrono::duration_cast<std::chrono::milliseconds>(t_2 - t_1).count() << "\n";
   std::cout << "lambda: " << std::chrono::duration_cast<std::chrono::milliseconds>(t_3 - t_2).count() << "\n";
}