view lib/exec.h @ 23:c3fb5f666e2d

graphs: Two graph algorithms
author Lewin Bormann <lbo@spheniscida.de>
date Sun, 09 Apr 2023 17:17:04 +0200
parents d6798d2acfb3
children
line wrap: on
line source


#include <fmt/core.h>
#include <fmt/ranges.h>


#include <chrono>
#include <functional>
#include <string>
void timeit(std::function<void()> f, std::string name = std::string());

void benchmarkit(std::function<void()> f, std::string name = std::string(), std::function<void()> setup = [](){});

using std::function, std::string, std::chrono::high_resolution_clock;

template<typename Func>
concept is_void_function = std::is_void_v<std::invoke_result_t<Func>>;

template<typename F> requires is_void_function<F>
void timeit_f(F f, string name = string()) {
    auto begin = high_resolution_clock::now();

    f();

    auto after = high_resolution_clock::now();

    auto d = after - begin;
    decltype(d)::rep count = d.count();
    decltype(d)::period p;

    fmt::print("(void) {} :: {} s\n", name, static_cast<double>(p.num)/p.den * count); 
    return;
}

template<typename F> requires (!is_void_function<F>)
auto timeit_f(F f, string name = string()) -> decltype(f()) {
    auto begin = high_resolution_clock::now();

    auto result = f();

    auto after = high_resolution_clock::now();

    auto d = after - begin;
    decltype(d)::rep count = d.count();
    decltype(d)::period p;

    fmt::print("{} :: {} s\n", name, static_cast<double>(p.num)/p.den * count); 
    return result;
}

template<typename F>
void benchmarkit_f(F f, const string& name, function<void()> setup = []() {}) {
    int n = 1;
    const double min_duration = 0.1;

    while (true) {
        setup();
     
        fmt::print("Running {} for {} iterations\n", name, n);

        auto begin = high_resolution_clock::now();

        for (unsigned int i = 0; i < n; i += 1)
            f();

        auto end = high_resolution_clock::now();
        decltype(end-begin)::period p;
        auto seconds = (end-begin).count() * static_cast<double>(p.num)/p.den;
        if (seconds < min_duration) {
            n *= 2;
        } else {
            fmt::print("{} iterations took {} seconds ({} s/iter)\n", n, seconds, seconds/n);
            break;
        }
    }
}