Created
January 28, 2026 23:11
-
-
Save iDevelopThings/c58ed8ee3249515e8bd96ab36955b0f6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #pragma once | |
| inline std::string format_time_duration(std::chrono::nanoseconds duration) { | |
| using namespace std::literals; | |
| const auto nanoseconds = duration.count(); | |
| if (nanoseconds < 1000.0) | |
| return std::format("{} ns ({} ms)", nanoseconds, static_cast<float>(nanoseconds) / 1'000'000.0f); | |
| const auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(duration).count(); | |
| if (microseconds < 1000.0) | |
| return std::format("{} us ({} ms)", microseconds, static_cast<float>(microseconds) / 1000.0f); | |
| const auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count(); | |
| if (milliseconds < 1000.0) | |
| return std::format("{} ms", milliseconds); | |
| return std::format("{:.2f} s", static_cast<float>(milliseconds) / 1000.0f); | |
| } | |
| inline std::string format_time_duration(std::chrono::duration<double, std::milli> duration) { | |
| return format_time_duration(std::chrono::duration_cast<std::chrono::nanoseconds>(duration)); | |
| } | |
| struct TimedScope | |
| { | |
| private: | |
| inline static size_t max_log_name_length = 0; | |
| public: | |
| std::string name; | |
| std::chrono::high_resolution_clock::time_point started_at; | |
| std::chrono::high_resolution_clock::time_point ended_at; | |
| std::chrono::duration<double, std::milli> duration; | |
| bool b_log_on_destruct = true; | |
| int depth = -1; | |
| TimedScope(std::string name, bool log_on_destruct = true); | |
| [[nodiscard]] std::chrono::duration<double, std::milli> get_current_duration() const; | |
| void end(); | |
| void log(); | |
| ~TimedScope(); | |
| }; | |
| struct GlobalTimedScope | |
| { | |
| inline static GlobalTimedScope& get() { | |
| static GlobalTimedScope instance; | |
| return instance; | |
| } | |
| std::vector<std::unique_ptr<TimedScope>> scopes; | |
| int scope_depth = 0; | |
| struct Scope | |
| { | |
| std::string name; | |
| std::unique_ptr<TimedScope> scope; | |
| Scope(std::string name); | |
| std::chrono::duration<double, std::milli> get_current_duration() const; | |
| ~Scope(); | |
| }; | |
| ~GlobalTimedScope() { | |
| // log in reverse order | |
| // for (auto it = scopes.rbegin(); it != scopes.rend(); ++it) { | |
| // (*it)->log(); | |
| // } | |
| for (const auto& scope : scopes) { | |
| scope->log(); | |
| } | |
| } | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "util/timed_scope.h" | |
| TimedScope::TimedScope(std::string name, bool log_on_destruct): | |
| name(std::move(name)), | |
| started_at(std::chrono::high_resolution_clock::now()), | |
| duration(0), | |
| b_log_on_destruct(log_on_destruct) { | |
| max_log_name_length = std::max(max_log_name_length, this->name.length()); | |
| } | |
| std::chrono::duration<double, std::milli> TimedScope::get_current_duration() const { | |
| auto now = std::chrono::high_resolution_clock::now(); | |
| return now - started_at; | |
| } | |
| void TimedScope::end() { | |
| if (ended_at.time_since_epoch().count() == 0) { | |
| ended_at = std::chrono::high_resolution_clock::now(); | |
| duration = ended_at - started_at; | |
| } | |
| } | |
| void TimedScope::log() { | |
| end(); | |
| if (depth >= 0) { | |
| std::cout << std::right << std::string(depth * 2, '-'); | |
| } | |
| const std::streamsize maxLog = static_cast<std::streamsize>(max_log_name_length) + (depth >= 0 ? depth * 2 : 0) + 2; | |
| std::cout << std::setw(maxLog) << std::left << std::setfill('.') << name << " "; | |
| std::cout << std::setprecision(2) << format_time_duration(duration) << "\n"; | |
| } | |
| TimedScope::~TimedScope() { | |
| if (!b_log_on_destruct) return; | |
| end(); | |
| log(); | |
| } | |
| GlobalTimedScope::Scope::Scope(std::string name): | |
| name(std::move(name)) { | |
| scope = std::make_unique<TimedScope>(this->name, false); | |
| scope->depth = get().scope_depth++; | |
| } | |
| std::chrono::duration<double, std::milli> GlobalTimedScope::Scope::get_current_duration() const { | |
| auto now = std::chrono::high_resolution_clock::now(); | |
| return now - scope->started_at; | |
| } | |
| GlobalTimedScope::Scope::~Scope() { | |
| get().scope_depth--; | |
| scope->end(); | |
| get().scopes.push_back(std::move(scope)); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment