#ifdef NDEBUG
#undef NDEBUG
#endif
#include <cassert>
#include <chrono>
#include <functional>
#include <iostream>
#include <vector>
typedef unsigned long long Integer;
struct Functor
{
void operator()(Integer i, Integer &sum) const
{
sum += i;
if ( i > 0 )
{
this->operator()(i - 1, sum);
}
}
};
void recurse(Integer i, Integer& sum)
{
sum += i;
if ( i > 0 )
{
recurse(i - 1, sum);
}
}
int main()
{
const Integer n(1000ull * 1000ull);
const auto t_0(std::chrono::high_resolution_clock::now());
Integer sum(0);
recurse(n, sum);
const auto t_1(std::chrono::high_resolution_clock::now());
std::function<void(Integer, Integer&)> lambda_recurse([&lambda_recurse](Integer i, Integer& l_sum)
{
l_sum += i;
if ( i > 0 )
{
lambda_recurse(i - 1, l_sum);
}
});
Integer lambda_sum(0);
lambda_recurse(n, lambda_sum);
const auto t_2(std::chrono::high_resolution_clock::now());
Integer functor_sum(0);
Functor functor;
functor(n, functor_sum);
const auto t_3(std::chrono::high_resolution_clock::now());
assert ( sum == lambda_sum );
assert ( sum == functor_sum );
std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(t_1 - t_0).count() << "\n";
std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(t_2 - t_1).count() << "\n";
std::cout << std::chrono::duration_cast<std::chrono::nanoseconds>(t_3 - t_2).count() << "\n";
}
CiNpZmRlZiBOREVCVUcKI3VuZGVmIE5ERUJVRwojZW5kaWYKI2luY2x1ZGUgPGNhc3NlcnQ+CiNpbmNsdWRlIDxjaHJvbm8+CiNpbmNsdWRlIDxmdW5jdGlvbmFsPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDx2ZWN0b3I+CiAKdHlwZWRlZiB1bnNpZ25lZCBsb25nIGxvbmcgSW50ZWdlcjsKCnN0cnVjdCBGdW5jdG9yCnsKICAgdm9pZCBvcGVyYXRvcigpKEludGVnZXIgaSwgSW50ZWdlciAmc3VtKSBjb25zdAogICB7CiAgICAgIHN1bSArPSBpOwogICAgICBpZiAoIGkgPiAwICkKICAgICAgewogICAgICAgICB0aGlzLT5vcGVyYXRvcigpKGkgLSAxLCBzdW0pOwogICAgICB9CiAgIH0KfTsKCnZvaWQgcmVjdXJzZShJbnRlZ2VyIGksIEludGVnZXImIHN1bSkKewogICBzdW0gKz0gaTsKICAgaWYgKCBpID4gMCApCiAgIHsKICAgICAgcmVjdXJzZShpIC0gMSwgc3VtKTsKICAgfQp9CiAKaW50IG1haW4oKQp7CiAgIGNvbnN0IEludGVnZXIgbigxMDAwdWxsICogMTAwMHVsbCk7CiAgIGNvbnN0IGF1dG8gdF8wKHN0ZDo6Y2hyb25vOjpoaWdoX3Jlc29sdXRpb25fY2xvY2s6Om5vdygpKTsKICAgSW50ZWdlciBzdW0oMCk7CiAgIHJlY3Vyc2Uobiwgc3VtKTsKICAgY29uc3QgYXV0byB0XzEoc3RkOjpjaHJvbm86OmhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6bm93KCkpOwogICBzdGQ6OmZ1bmN0aW9uPHZvaWQoSW50ZWdlciwgSW50ZWdlciYpPiBsYW1iZGFfcmVjdXJzZShbJmxhbWJkYV9yZWN1cnNlXShJbnRlZ2VyIGksIEludGVnZXImIGxfc3VtKQogICB7CiAgICAgIGxfc3VtICs9IGk7CiAgICAgIGlmICggaSA+IDAgKQogICAgICB7CiAgICAgICAgIGxhbWJkYV9yZWN1cnNlKGkgLSAxLCBsX3N1bSk7CiAgICAgIH0KICAgfSk7CiAgIEludGVnZXIgbGFtYmRhX3N1bSgwKTsKICAgbGFtYmRhX3JlY3Vyc2UobiwgbGFtYmRhX3N1bSk7CiAgIGNvbnN0IGF1dG8gdF8yKHN0ZDo6Y2hyb25vOjpoaWdoX3Jlc29sdXRpb25fY2xvY2s6Om5vdygpKTsKICAgSW50ZWdlciBmdW5jdG9yX3N1bSgwKTsKICAgRnVuY3RvciBmdW5jdG9yOwogICBmdW5jdG9yKG4sIGZ1bmN0b3Jfc3VtKTsKICAgY29uc3QgYXV0byB0XzMoc3RkOjpjaHJvbm86OmhpZ2hfcmVzb2x1dGlvbl9jbG9jazo6bm93KCkpOwogICBhc3NlcnQgKCBzdW0gPT0gbGFtYmRhX3N1bSApOwogICBhc3NlcnQgKCBzdW0gPT0gZnVuY3Rvcl9zdW0gKTsKICAgc3RkOjpjb3V0IDw8IHN0ZDo6Y2hyb25vOjpkdXJhdGlvbl9jYXN0PHN0ZDo6Y2hyb25vOjpuYW5vc2Vjb25kcz4odF8xIC0gdF8wKS5jb3VudCgpIDw8ICJcbiI7CiAgIHN0ZDo6Y291dCA8PCBzdGQ6OmNocm9ubzo6ZHVyYXRpb25fY2FzdDxzdGQ6OmNocm9ubzo6bmFub3NlY29uZHM+KHRfMiAtIHRfMSkuY291bnQoKSA8PCAiXG4iOwogICBzdGQ6OmNvdXQgPDwgc3RkOjpjaHJvbm86OmR1cmF0aW9uX2Nhc3Q8c3RkOjpjaHJvbm86Om5hbm9zZWNvbmRzPih0XzMgLSB0XzIpLmNvdW50KCkgPDwgIlxuIjsKfQ==