Fix warning
[TortoiseGit.git] / src / Utils / ProfilingInfo.cpp
blob67aa715ce152cf9a7bac39df0bc8a8e67ebd5a6a
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2008, 2014 - TortoiseSVN
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "stdafx.h"
22 #ifndef __INTRIN_H_
23 #include <intrin.h>
24 #endif
26 #include "ProfilingInfo.h"
28 #ifdef _DEBUG
30 //////////////////////////////////////////////////////////////////////
31 /// construction / destruction
32 //////////////////////////////////////////////////////////////////////
34 CRecordProfileEvent::CRecordProfileEvent (CProfilingRecord* aRecord)
35 : record (aRecord)
36 , start (__rdtsc())
40 CRecordProfileEvent::~CRecordProfileEvent()
42 if (record)
43 record->Add (__rdtsc() - start);
46 #endif
48 //////////////////////////////////////////////////////////////////////
49 // construction / destruction
50 //////////////////////////////////////////////////////////////////////
52 CProfilingRecord::CProfilingRecord ( const char* name
53 , const char* file
54 , int line)
55 : name (name)
56 , file (file)
57 , line (line)
58 , count (0)
59 , sum (0)
60 , minValue (ULLONG_MAX)
61 , maxValue (0)
65 //////////////////////////////////////////////////////////////////////
66 // record values
67 //////////////////////////////////////////////////////////////////////
69 void CProfilingRecord::Add (unsigned __int64 value)
71 ++count;
72 sum += value;
74 if (value < minValue)
75 minValue = value;
76 if (value > maxValue)
77 maxValue = value;
80 //////////////////////////////////////////////////////////////////////
81 // modification
82 //////////////////////////////////////////////////////////////////////
84 void CProfilingRecord::Reset()
86 count = 0;
87 sum = 0;
89 minValue = LLONG_MAX;
90 maxValue = 0;
93 //////////////////////////////////////////////////////////////////////
94 // construction / destruction
95 //////////////////////////////////////////////////////////////////////
97 CProfilingInfo::CProfilingInfo()
101 CProfilingInfo::~CProfilingInfo(void)
103 if (!records.empty())
105 // write profile to file
107 TCHAR buffer [MAX_PATH] = {0};
108 if (GetModuleFileNameEx(GetCurrentProcess(), nullptr, buffer, _countof(buffer)) > 0)
111 std::wstring fileName (buffer);
112 fileName += L".profile";
114 std::string report = GetInstance()->GetReport();
116 CFile file (fileName.c_str(), CFile::modeCreate | CFile::modeWrite );
117 file.Write (report.c_str(), (UINT)report.size());
119 catch (...)
121 // ignore all file errors etc.
125 // free data
127 for (size_t i = 0; i < records.size(); ++i)
128 delete records[i];
132 //////////////////////////////////////////////////////////////////////
133 // access to default instance
134 //////////////////////////////////////////////////////////////////////
136 CProfilingInfo* CProfilingInfo::GetInstance()
138 static CProfilingInfo instance;
139 return &instance;
142 //////////////////////////////////////////////////////////////////////
143 // create a report
144 //////////////////////////////////////////////////////////////////////
146 static std::string IntToStr (unsigned __int64 value)
148 char buffer[100] = { 0 };
149 _ui64toa_s (value, buffer, 100, 10);
151 std::string result = buffer;
152 for (size_t i = 3; i < result.length(); i += 4)
153 result.insert (result.length() - i, 1, ',');
155 return result;
158 std::string CProfilingInfo::GetReport() const
160 enum { LINE_LENGTH = 500 };
162 char lineBuffer [LINE_LENGTH];
163 const char * const format ="%10s%17s%17s%17s%6s %s\t%s\n";
165 std::string result;
166 result.reserve (LINE_LENGTH * records.size());
167 sprintf_s ( lineBuffer, format, "count", "sum", "min", "max", "line", "name", "file");
168 result += lineBuffer;
170 for (auto iter = records.cbegin(), end = records.cend()
171 ; iter != end
172 ; ++iter)
174 unsigned __int64 minValue = (*iter)->GetMinValue();
175 if (minValue == ULLONG_MAX)
176 minValue = 0;
178 sprintf_s(lineBuffer, format
179 , IntToStr ((*iter)->GetCount()).c_str()
180 , IntToStr ((*iter)->GetSum()).c_str()
181 , IntToStr (minValue).c_str()
182 , IntToStr ((*iter)->GetMaxValue()).c_str()
184 , IntToStr ((*iter)->GetLine()).c_str()
185 , (*iter)->GetName()
186 , (*iter)->GetFile());
188 result += lineBuffer;
191 return result;
194 //////////////////////////////////////////////////////////////////////
195 // add a new record
196 //////////////////////////////////////////////////////////////////////
198 CProfilingRecord* CProfilingInfo::Create ( const char* name, const char* file, int line)
200 CProfilingRecord* record = new CProfilingRecord (name, file, line);
201 records.push_back (record);
203 return record;