forked from Sneeds-Feed-and-Seed/sneedacity
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProfiler.cpp
156 lines (125 loc) · 4.18 KB
/
Profiler.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
/**********************************************************************
Sneedacity: A Digital Audio Editor
Profiler.cpp
Created by Michael Chinen (mchinen) on 8/12/08
Sneedacity(R) is copyright (c) 1999-2008 Sneedacity Team.
License: GPL v2. See License.txt.
******************************************************************//**
\class Profiler
\brief A simple profiler to measure the average time lengths that a
particular task/function takes. Currently not thread-safe and not thread-smart,
but it will probably work fine if you use it on a high level.
\class TaskProfile
\brief a simple class to keep track of one task that may be called multiple times.
*//*******************************************************************/
#include "Profiler.h"
#include <stdio.h>
#include <string.h>
#include <wx/crt.h>
///write to a profile at the end of the test.
Profiler::~Profiler()
{
if(mTasks.size())
{
//print everything out. append to a log.
FILE* log = fopen("SneedacityProfilerLog.txt", "a");
time_t now;
time(&now);
wxFprintf(log,"Sneedacity Profiler Run, Ended at ");
wxFprintf(log,"%s",ctime(&now));
wxFprintf(log,"****************************************\n");
//print out the tasks
for(int i=0;i<(int)mTasks.size();i++)
{
if(mTasks[i]->mNumHits>0)
{
wxFprintf(log,"Task: %s\n(begins at line %d in %s)\n\n",mTasks[i]->mDescription.get(), mTasks[i]->mLine, mTasks[i]->mFileName.get());
wxFprintf(log,"Number of times run: %d\n",mTasks[i]->mNumHits);
wxFprintf(log,"Total run time (seconds): %f\n", (double)mTasks[i]->mCumTime/CLOCKS_PER_SEC);
wxFprintf(log,"Average run time (seconds): %f\n",mTasks[i]->ComputeAverageRunTime());
if(i < ((int)mTasks.size()) -1)
wxFprintf(log,"----------------------------\n");
}
}
wxFprintf(log,"\n****************************************\n\n\n");
fclose(log);
}
}
///start the task timer.
void Profiler::Begin(const char* fileName, int lineNum, const char* taskDescription)
{
std::lock_guard<std::mutex> guard{ mTasksMutex };
GetOrCreateTaskProfile(fileName,lineNum)->Begin(fileName,lineNum,taskDescription);
}
///end the task timer.
void Profiler::End(const char* fileName, int lineNum, const char* taskDescription)
{
std::lock_guard<std::mutex> guard{ mTasksMutex };
TaskProfile* tp;
tp=GetTaskProfileByDescription(taskDescription);
if(tp)
tp->End(fileName,lineNum,taskDescription);
}
///Gets the singleton instance
Profiler* Profiler::Instance()
{
static Profiler pro;
//this isn't 100% threadsafe but I think Okay for this purpose.
return &pro;
}
///find a taskProfile for the given task, otherwise create
TaskProfile* Profiler::GetOrCreateTaskProfile(const char* fileName, int lineNum)
{
for(int i=0;i<(int)mTasks.size();i++)
{
if(strcmp(fileName, mTasks[i]->mFileName.get())==0 && lineNum == mTasks[i]->mLine)
return mTasks[i].get();
}
auto tp = std::make_unique<TaskProfile>();
mTasks.push_back(std::move(tp));
return mTasks.back().get();
}
TaskProfile* Profiler::GetTaskProfileByDescription(const char* description)
{
for(int i=0;i<(int)mTasks.size();i++)
{
if(strcmp(description, mTasks[i]->mDescription.get())==0)
return mTasks[i].get();
}
return NULL;
}
///Task Profile
TaskProfile::TaskProfile()
{
mCumTime=0;
mNumHits=0;
}
TaskProfile::~TaskProfile()
{
}
///start the task timer.
void TaskProfile::Begin(const char* fileName, int lineNum, const char* taskDescription)
{
if(!mFileName)
{
mFileName.reinit( strlen(fileName) + 1 );
strcpy(mFileName.get(), fileName);
mDescription.reinit( strlen(taskDescription) + 1 );
strcpy(mDescription.get(), taskDescription);
mLine = lineNum;
}
mLastTime = clock();
}
///end the task timer.
void TaskProfile::End(const char* WXUNUSED(fileName), int WXUNUSED(lineNum), const char* WXUNUSED(taskDescription))
{
mCumTime += clock() - mLastTime;
mNumHits++;
}
double TaskProfile::ComputeAverageRunTime()
{
if(mNumHits)
return (double) ((double)mCumTime/CLOCKS_PER_SEC)/mNumHits;
else
return 0.0;
}