Just™ Game Engine
profiling.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2021-2022 Konstanty Misiak
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7#pragma once
8
9#define JNG_PROFILING_ENABLED 0
10#if JNG_PROFILING_ENABLED
11
12#include <chrono>
13#include <thread>
14#include <mutex>
15
16namespace jng {
17
18 class Profiler
19 {
20 public:
21 struct Result {
22 std::string name;
23 long long start, end;
24 };
25
26 void beginSession(const std::string& filepath);
27 void endSession();
28 void addProfile(const Result& result);
29
30 static Profiler& get() { return s_instance; }
31 private:
32 Profiler() = default;
33
34 void writeHeader();
35 void writeFooter();
36
37 std::ofstream m_output;
38 std::mutex m_mutex;
39
40 static Profiler s_instance;
41 };
42
43 class ProfilingTimer
44 {
45 public:
46 ProfilingTimer(const char* name) :
47 m_name(name),
48 m_startTS(std::chrono::steady_clock::now())
49 {}
50
51 ~ProfilingTimer()
52 {
53 auto endTS = std::chrono::steady_clock::now();
54
55 Profiler::get().addProfile({
56 m_name,
57 std::chrono::time_point_cast<std::chrono::microseconds>(m_startTS).time_since_epoch().count(),
58 std::chrono::time_point_cast<std::chrono::microseconds>(endTS).time_since_epoch().count()
59 });
60 }
61 private:
62 std::string m_name;
63 std::chrono::time_point<std::chrono::steady_clock> m_startTS;
64 };
65
66 template<size_t SIZE>
67 constexpr auto cleanupStringForProfiler(const char(&str)[SIZE])
68 {
69 constexpr size_t arrSize = 3;
70 constexpr const char* remove[arrSize] = {
71 "__cdecl ",
72 "class ",
73 "struct "
74 };
75 constexpr size_t removeSize[3] = { 9, 7, 8 };
76 char result[SIZE];
77
78 size_t dstIndex = 0;
79 for (size_t srcIndex = 0; srcIndex < SIZE; ++srcIndex)
80 {
81 for (size_t i = 0; i < arrSize; ++i)
82 {
83 size_t matchIndex = 0;
84 while (matchIndex < removeSize[i] - 1 && srcIndex + matchIndex < SIZE - 1 && str[srcIndex + matchIndex] == remove[i][matchIndex])
85 matchIndex++;
86 if (matchIndex == removeSize[i] - 1)
87 srcIndex += matchIndex;
88 }
89
90 result[dstIndex++] = str[srcIndex] == '"' ? '\'' : str[srcIndex];
91 }
92 return std::string(result);
93}
94
95} // namespace jng
96
97#if defined(__FUNCSIG__)
98#define __JNG_FUNCSIG __FUNCSIG__
99#else
100#define __JNG_FUNCSIG __PRETTY_FUNCTION__
101#endif
102
103#define JNG_PROFILE_BEGIN_SESSION(filepath) jng::Profiler::get().beginSession(filepath)
104#define JNG_PROFILE_END_SESSION() jng::Profiler::get().endSession()
105#define __JNG_CONCAT(x, y) x##y
106#define __JNG_PROFILE_SCOPE(name, line) jng::ProfilingTimer __JNG_CONCAT(timer, line)(jng::cleanupStringForProfiler(name).c_str())
107#define JNG_PROFILE_SCOPE(name) __JNG_PROFILE_SCOPE(name, __LINE__)
108#define JNG_PROFILE_FUNCTION() JNG_PROFILE_SCOPE(__JNG_FUNCSIG)
109
110#else
111
112#define JNG_PROFILE_BEGIN_SESSION(filepath)
113#define JNG_PROFILE_END_SESSION()
114#define JNG_PROFILE_SCOPE(name)
115#define JNG_PROFILE_FUNCTION()
116
117#endif
Definition: base.hpp:11