-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtimeline.h
141 lines (118 loc) · 3.37 KB
/
timeline.h
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
#ifndef __NEWPLAN_TOOLKIT_TIMELINE_H__
#define __NEWPLAN_TOOLKIT_TIMELINE_H__
#include <iostream>
#include <fstream>
#include <chrono>
#include <algorithm>
#include <thread>
namespace newplan_toolkit
{
#define PROFILING 1
#if PROFILING
#define PROFILE_SCOPE(name) InstrumentationTimer timer##__LINE__(name)
#define PROFILE_FUNCTION() PROFILE_SCOPE(__PRETTY_FUNCTION__)
#else
#define PROFILE_SCORE(name)
#endif
//当前监测的会话
struct InstrumentationSession
{
std::string name;
};
//检测结果数据
struct ProfileResult
{
std::string name; //调用栈函数名称
long long start, stop; //起止时间
uint32_t threadID; //线程ID
};
class Instrumentor
{
private:
InstrumentationSession* m_CurrentSession;
std::ofstream m_OutputStream;
int m_ProfileCount;
public:
Instrumentor() : m_CurrentSession(nullptr), m_ProfileCount(0)
{
}
void BeginSession(const std::string& name, const std::string& filepath = "result.json")
{
m_OutputStream.open(filepath);
WriteHeader();
m_CurrentSession = new InstrumentationSession{ name };
}
void EndSession()
{
WriteFooter();
m_OutputStream.close();
delete m_CurrentSession;
m_CurrentSession = nullptr;
m_ProfileCount = 0;
}
void WriteProfile(const ProfileResult& result)
{
if (m_ProfileCount++ > 0)
{
m_OutputStream << ",";
}
std::string name = result.name;
std::replace(name.begin(), name.end(), '"', '\'');
m_OutputStream << "{";
m_OutputStream << "\"cat\":\"function\",";
m_OutputStream << "\"dur\":" << (result.stop - result.start) << ",";
m_OutputStream << "\"name\":\"" << name << "\",";
m_OutputStream << "\"ph\":\"X\",";
m_OutputStream << "\"pid\": 0,";
m_OutputStream << "\"tid\": \"" << result.threadID << "\",";
m_OutputStream << "\"ts\": " << result.start;
m_OutputStream << "}";
m_OutputStream.flush();
}
void WriteHeader()
{
m_OutputStream << "{\"otherData\": {}, \"traceEvents\": [";
m_OutputStream.flush();
}
void WriteFooter()
{
m_OutputStream << "]}";
m_OutputStream.flush();
}
static Instrumentor& Get()
{
static Instrumentor* instance = new Instrumentor();
return *instance;
}
};
//计时器
class InstrumentationTimer
{
private:
std::string title;
std::chrono::high_resolution_clock::time_point m_start;
bool m_stoped;
public:
InstrumentationTimer(const std::string& title) : title(title), m_stoped(false)
{
m_start = std::chrono::high_resolution_clock::now();
}
~InstrumentationTimer()
{
if (!m_stoped)
{
stop();
}
}
void stop()
{
auto m_stop = std::chrono::high_resolution_clock::now();
long long start = std::chrono::time_point_cast<std::chrono::microseconds>(m_start).time_since_epoch().count();
long long stop = std::chrono::time_point_cast<std::chrono::microseconds>(m_stop).time_since_epoch().count();
uint32_t threadID = std::hash<std::thread::id>{}(std::this_thread::get_id());
Instrumentor::Get().WriteProfile({ title, start, stop, threadID});
m_stoped = true;
}
};
};// end namespace newplan_toolkit
#endif