Limit GUI updates the the main thread
[TortoiseGit.git] / src / Utils / ProfilingInfo.cpp
blob0bec93d614f204f12162df0bbf82e325ff4650cb
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2003-2008 - 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];
108 if (GetModuleFileNameEx (GetCurrentProcess(), NULL, buffer, MAX_PATH) > 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];
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
168 , "count", "sum", "min", "max"
169 , "line", "name", "file");
170 result += lineBuffer;
172 for ( TRecords::const_iterator iter = records.begin(), end = records.end()
173 ; iter != end
174 ; ++iter)
176 unsigned __int64 minValue = (*iter)->GetMinValue();
177 if (minValue == ULLONG_MAX)
178 minValue = 0;
180 sprintf_s ( lineBuffer, format
182 , IntToStr ((*iter)->GetCount()).c_str()
183 , IntToStr ((*iter)->GetSum()).c_str()
184 , IntToStr (minValue).c_str()
185 , IntToStr ((*iter)->GetMaxValue()).c_str()
187 , IntToStr ((*iter)->GetLine()).c_str()
188 , (*iter)->GetName()
189 , (*iter)->GetFile());
191 result += lineBuffer;
194 return result;
197 //////////////////////////////////////////////////////////////////////
198 // add a new record
199 //////////////////////////////////////////////////////////////////////
201 CProfilingRecord* CProfilingInfo::Create ( const char* name
202 , const char* file
203 , int line)
205 CProfilingRecord* record = new CProfilingRecord (name, file, line);
206 records.push_back (record);
208 return record;