-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPerformanceTrace.hpp
More file actions
157 lines (141 loc) · 4.08 KB
/
PerformanceTrace.hpp
File metadata and controls
157 lines (141 loc) · 4.08 KB
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
#pragma once
#include<chrono>
#include<list>
#include<vector>
#include<string>
#include<map>
#include<thread>
#include<mutex>
#include<fstream>
#include<iomanip>
#include<debugapi.h>
using namespace std;
using namespace chrono;
void ThreadProc(void* param);
class CPerformanceTrace{
public:
CPerformanceTrace(const char* PerformanceTracerName = "")
{
m_Info["TracerName"] = PerformanceTracerName;
AddCount();
//m_WriteThread = thread(ThreadProc,this);
}
~CPerformanceTrace()
{
}
enum TimeUnit{
TU_Nano,
TU_Micro,
TU_Milli,
TU_Sec,
TU_Min,
TU_Hour
};
enum ErrorCode{
PTEC_TimeEmpty = -100,
PTEC_UnhandledTimeUnit
};
void AddCount(){ m_CountedTime.emplace_back(steady_clock::now());}
void Reset(){ m_CountedTime.clear();}
void ResetWithCount(){ Reset(); m_CountedTime.emplace_back(steady_clock::now());}
void WriteThread();
__int64 GetTime(TimeUnit unit = TimeUnit::TU_Milli);
template<typename T>
__int64 GetTimeCount(T duration, TimeUnit unit = TimeUnit::TU_Milli);
void DisplayTime(string str, TimeUnit uint = TimeUnit::TU_Milli);
private:
list<decltype(steady_clock::now())> m_CountedTime;
map<string,string> m_Info;
list<string> m_write;
mutex m_mutex;
thread m_WriteThread;
};
__int64 CPerformanceTrace::GetTime(TimeUnit unit)
{
if(m_CountedTime.size() == 0)
return ErrorCode::PTEC_TimeEmpty;
auto diff = steady_clock::now() - m_CountedTime.back();
switch(unit)
{
case TimeUnit::TU_Nano: return duration_cast<nanoseconds>(diff).count();
case TimeUnit::TU_Micro: return duration_cast<microseconds>(diff).count();
case TimeUnit::TU_Milli: return duration_cast<milliseconds>(diff).count();
case TimeUnit::TU_Sec: return duration_cast<seconds>(diff).count();
case TimeUnit::TU_Min: return duration_cast<minutes>(diff).count();
case TimeUnit::TU_Hour: return duration_cast<hours>(diff).count();
default: return ErrorCode::PTEC_UnhandledTimeUnit;
}
}
template<typename T>
__int64 CPerformanceTrace::GetTimeCount(T duration, TimeUnit unit)
{
switch(unit)
{
case TimeUnit::TU_Nano: return duration_cast<nanoseconds>(duration).count();
case TimeUnit::TU_Micro: return duration_cast<microseconds>(duration).count();
case TimeUnit::TU_Milli: return duration_cast<milliseconds>(duration).count();
case TimeUnit::TU_Sec: return duration_cast<seconds>(duration).count();
case TimeUnit::TU_Min: return duration_cast<minutes>(duration).count();
case TimeUnit::TU_Hour: return duration_cast<hours>(duration).count();
default: return ErrorCode::PTEC_UnhandledTimeUnit;
}
}
void CPerformanceTrace::DisplayTime(string str, TimeUnit unit)
{
if(m_CountedTime.size() == 0)
return;
AddCount();
auto *first = &m_CountedTime.front();
stringstream ss;
for(auto& i : m_CountedTime)
{
if(first == &i) continue;
auto diff = i - *first;
auto result = GetTimeCount(diff,unit);
if(!ss.str().empty()) ss << ",";
if(result < 0)
ss << "0";
else
ss << setw(3) << result;
first = &i;
}
m_Info["time"] = ss.str();
m_Info["total"] = to_string(GetTimeCount(m_CountedTime.back() - m_CountedTime.front()));
/*ofstream out((string("D:\\") + m_Info["TracerName"] + ".txt"),ios::app);
out << m_Info["total"] << endl;
out.close();*/
string prefix("{"), suffix("}");
while(1)
{
string::size_type pos = string::size_type(0);
auto prefix_pos = str.find_first_of(prefix, pos);
if(prefix_pos == string::npos) break;
auto suffix_pos = str.find_first_of(suffix, pos);
if(suffix_pos == string::npos) break;
string keyword(str,prefix_pos + prefix.size(),suffix_pos - prefix_pos - suffix.size());
auto result = m_Info.find(keyword);
if(result != m_Info.end())
str.replace(prefix_pos,suffix_pos - prefix_pos + suffix.size(), m_Info[keyword]);
pos = suffix_pos + suffix.size();
}
OutputDebugStringA((str+"\n").c_str());
}
void CPerformanceTrace::WriteThread()
{
ofstream out((string("D:\\") + m_Info["TracerName"] + ".txt"));
while(1)
{
m_mutex.lock();
while(!m_write.empty())
{
out << m_write.front() << endl;
m_write.pop_front();
}
m_mutex.unlock();
Sleep(30);
}
}
void ThreadProc(void* param)
{
((CPerformanceTrace*)param)->WriteThread();
}