Skip to content

Instantly share code, notes, and snippets.

@kuvaldini
Created February 20, 2024 19:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kuvaldini/3d88563d7c541f662f79e3b5c9aabada to your computer and use it in GitHub Desktop.
Save kuvaldini/3d88563d7c541f662f79e3b5c9aabada to your computer and use it in GitHub Desktop.
Profiler for C++ tracks time consumption in scope {}
#pragma once
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <chrono>
#include <cstdio>
#include <unistd.h>
#include <fmt/chrono.h>
#include "fmt_eprint.hpp"
// *INDENT-OFF*
struct separate_thousands : std::numpunct<char> {
char_type do_thousands_sep() const override { return '\''; } // separate with commas
string_type do_grouping() const override { return "\3"; } // groups of 3 digit
};
template<typename T> struct scoped_locale_change {
std::locale prev_locale;
scoped_locale_change(){
// prev_locale = std::cout.getloc();
// std::cout.imbue( std::locale( std::cout.getloc(), thousands.release() ) );
auto thousands = std::make_unique<separate_thousands>();
prev_locale = std::locale::global( std::locale( std::cout.getloc(), thousands.release() ) );
}
~scoped_locale_change(){
std::locale::global( prev_locale );
}
};
// *INDENT-ON*
struct ProfiledScope
{
std::string name{"unnamed"};
std::chrono::steady_clock::time_point timepoint_begin = std::chrono::steady_clock::now();
~ProfiledScope()
{
scoped_locale_change<separate_thousands> slc;
fmt::eprint( "-- ProfiledScope {} elapsed {:L}ns\n", name, ( std::chrono::steady_clock::now() - timepoint_begin ).count() );
}
};
struct ProfiledScope2
{
private:
std::chrono::steady_clock::time_point timepoint_begin = std::chrono::steady_clock::now();
std::string name{"unnamed"};
public:
ProfiledScope2( std::string &&name ) : name( name ) {}
~ProfiledScope2()
{
auto const elapsed = std::chrono::steady_clock::now() - timepoint_begin;
auto &info = ProfiledScope2::the_map[name];
info.elapsed += elapsed;
info.calls_count += 1;
}
struct ElapsedCount
{
std::chrono::steady_clock::duration elapsed{0};
size_t calls_count{0};
};
private: //static
static std::map<std::string, ElapsedCount> the_map;
public: // static
static void report()
{
scoped_locale_change<separate_thousands> slc;
for( auto const &each : ProfiledScope2::the_map )
{
auto const &name = each.first;
auto const &elapsed = each.second.elapsed;
auto const &calls_count = each.second.calls_count;
auto const avg = elapsed / calls_count;
fmt::eprint( "-- ProfiledScope2 {} totally elapsed {:L}ns during n:{} calls avg:{:L}ns todoMAX:_ todoMAXatIDX:_ \n",
name, elapsed.count(), calls_count, ( unsigned long long )avg.count() );
}
}
};
// /*static*/ std::map<std::string, ProfiledScope2::ElapsedCount> ProfiledScope2::the_map; //ToDo not required in C++17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment