mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-04 17:49:45 +02:00
159 lines
4.2 KiB
C++
159 lines
4.2 KiB
C++
/**********************************************************************
|
|
|
|
Audacity: A Digital Audio Editor
|
|
|
|
Profiler.cpp
|
|
|
|
Created by Michael Chinen (mchinen) on 8/12/08
|
|
Audacity(R) is copyright (c) 1999-2008 Audacity 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 "Audacity.h"
|
|
#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("AudacityProfilerLog.txt", "a");
|
|
time_t now;
|
|
|
|
time(&now);
|
|
wxFprintf(log,"Audacity 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)
|
|
{
|
|
mTasksMutex.Lock();
|
|
GetOrCreateTaskProfile(fileName,lineNum)->Begin(fileName,lineNum,taskDescription);
|
|
mTasksMutex.Unlock();
|
|
}
|
|
|
|
///end the task timer.
|
|
void Profiler::End(const char* fileName, int lineNum, const char* taskDescription)
|
|
{
|
|
mTasksMutex.Lock();
|
|
TaskProfile* tp;
|
|
tp=GetTaskProfileByDescription(taskDescription);
|
|
if(tp)
|
|
tp->End(fileName,lineNum,taskDescription);
|
|
mTasksMutex.Unlock();
|
|
}
|
|
|
|
///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;
|
|
}
|