-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTimeProfiler.cpp
167 lines (152 loc) · 3.91 KB
/
TimeProfiler.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#include<iostream>
#include<fstream>
#include<string>
#include<chrono>
#include<algorithm>
#include<thread>
#include<cmath>
//该宏定义用于创建独一无二的timer(为了避免profiling作用域的重复所以与行绑定)
//This macro definition is used to create a unique timer (bound to a row to avoid duplication of the profiling scope)
#define PROFILE_BASE(FuncName) ProfileTimer timer##__LINE__(FuncName)
//该宏定义用于将函数名称(真名)直接绑定(这样就不用自主输入函数名称了)
//This macro definition is used to bind the function name (real name) directly (so that you don't have to enter the function name yourself)
#define PROFILE_ACT() PROFILE_BASE(__FUNCSIG__)
struct ProfileResult
{
std::string FuncName;
long long Start, End;
uint32_t TempThread;
};
struct ProfileSession
{
std::string FuncName;
};
class Profiler
{
private:
ProfileSession* CurrentSession;
std::ofstream OutputStream;
uint32_t ProfileCount;
public:
Profiler():CurrentSession(nullptr),ProfileCount(0){}
void BeginSession(const std::string& FuncName, const std::string& filepath = "Results.json")
{
OutputStream.open(filepath);
WriteHeader();
CurrentSession = new ProfileSession();
}
void EndSession()
{
WriteFooter();
OutputStream.close();
delete CurrentSession;
CurrentSession = nullptr;
ProfileCount = 0;
}
void WriteProfile(const ProfileResult& result)
{
if (ProfileCount++ > 0)
{
OutputStream << ",";
}
std::string FuncName = result.FuncName;
//将所有双引号字符替换为单引号(使用到了转义符\下同)
std::replace(FuncName.begin(), FuncName.end(), '"', '\'');
//构建json结构(键值对):这一键值对是根据Chrome的Trace Viewer Format构建的
OutputStream << "{";
//事件分类category
OutputStream << "\"cat\":\"Process Function\",";
//历程duration
OutputStream << "\"dur\":" << (result.End - result.Start) << ',';
//事件名name
OutputStream << "\"name\":\"" << FuncName <<"\",";
//阶段phase
OutputStream << "\"ph\":\"X\",";
//进程名pid
OutputStream << "\"pid\":\"Profiling\",";
//线程名tid
OutputStream << "\"tid\":" << result.TempThread << ",";
//时间戳ts
OutputStream << "\"ts\":" << result.Start;
OutputStream << "}";
//使用flush不等待输出缓冲直接将输出内容写入
OutputStream.flush();
}
void WriteHeader()
{
OutputStream << "{\"ohterData\":{\"msg\":\"This is a visual version of profiling.\"},\"traceEvents\":[";
OutputStream.flush();
}
void WriteFooter()
{
OutputStream << "]}";
OutputStream.flush();
}
static Profiler& Get()
{
static Profiler* instance = new Profiler();
return *instance;
}
};
class ProfileTimer
{
private:
const char* FuncName;
std::chrono::time_point<std::chrono::steady_clock> StartPoint;
bool StopFlag;
public:
ProfileTimer(const char* FuncName) : FuncName(FuncName), StopFlag(false)
{
StartPoint = std::chrono::high_resolution_clock::now();
}
void Stop()
{
auto EndPoint = std::chrono::high_resolution_clock::now();
long long start = std::chrono::time_point_cast<std::chrono::microseconds>(StartPoint).time_since_epoch().count();
long long end = std::chrono::time_point_cast<std::chrono::microseconds>(EndPoint).time_since_epoch().count();
uint32_t TempThread = std::hash<std::thread::id>{}(std::this_thread::get_id());
Profiler::Get().WriteProfile({ FuncName, start, end, TempThread });
StopFlag = true;
}
~ProfileTimer()
{
if (!StopFlag)
{
Stop();
}
}
};
//示范 Demo
void Foo_One()
{
PROFILE_ACT();
for (int i = 0; i < 500; i++)
{
std::cout << "Count#" << i << std::endl;
}
}
void Foo_Two()
{
PROFILE_ACT();
for (int i = 0; i < 1000; i++)
{
std::cout << "Count#" << i << std::endl;
}
}
void BenchMark()
{
PROFILE_ACT();
Foo_One();
Foo_Two();
Foo_One();
Foo_Two();
}
/*
int main()
{
Profiler::Get().BeginSession("Profile");
BenchMark();
Profiler::Get().EndSession();
std::cin.get();
}
*/