2008-05-22 16:54:27 +00:00
|
|
|
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
|
|
|
|
|
|
|
|
|
/*
|
2012-09-09 16:57:42 +01:00
|
|
|
Rubber Band Library
|
2008-05-22 16:54:27 +00:00
|
|
|
An audio time-stretching and pitch-shifting library.
|
2023-01-10 11:10:06 +00:00
|
|
|
Copyright 2007-2023 Particular Programs Ltd.
|
2012-09-09 16:57:42 +01:00
|
|
|
|
2008-05-22 16:54:27 +00:00
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU General Public License as
|
|
|
|
|
published by the Free Software Foundation; either version 2 of the
|
|
|
|
|
License, or (at your option) any later version. See the file
|
|
|
|
|
COPYING included with this distribution for more information.
|
2012-09-09 16:57:42 +01:00
|
|
|
|
|
|
|
|
Alternatively, if you have a valid commercial licence for the
|
|
|
|
|
Rubber Band Library obtained by agreement with the copyright
|
|
|
|
|
holders, you may redistribute and/or modify it under the terms
|
|
|
|
|
described in that licence.
|
|
|
|
|
|
|
|
|
|
If you wish to distribute code using the Rubber Band Library
|
|
|
|
|
under terms other than those of the GNU General Public License,
|
|
|
|
|
you must obtain a valid commercial licence before doing so.
|
2008-05-22 16:54:27 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "Profiler.h"
|
|
|
|
|
|
2022-05-19 13:34:51 +01:00
|
|
|
#include "Thread.h"
|
2021-03-11 16:14:40 +00:00
|
|
|
|
2008-05-22 16:54:27 +00:00
|
|
|
#include <algorithm>
|
|
|
|
|
#include <set>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <map>
|
|
|
|
|
|
2012-09-09 16:57:42 +01:00
|
|
|
#include <stdio.h>
|
|
|
|
|
|
2020-12-10 09:25:28 +00:00
|
|
|
#ifdef _MSC_VER
|
2012-09-09 16:57:42 +01:00
|
|
|
// Ugh --cc
|
|
|
|
|
#define snprintf sprintf_s
|
|
|
|
|
#endif
|
2008-05-22 16:54:27 +00:00
|
|
|
|
|
|
|
|
namespace RubberBand {
|
|
|
|
|
|
|
|
|
|
#ifndef NO_TIMING
|
|
|
|
|
|
|
|
|
|
Profiler::ProfileMap
|
|
|
|
|
Profiler::m_profiles;
|
|
|
|
|
|
|
|
|
|
Profiler::WorstCallMap
|
|
|
|
|
Profiler::m_worstCalls;
|
|
|
|
|
|
2021-03-11 16:14:40 +00:00
|
|
|
static Mutex profileMutex;
|
|
|
|
|
|
2008-05-22 16:54:27 +00:00
|
|
|
void
|
2022-07-14 10:02:39 +01:00
|
|
|
Profiler::add(const char *id, double us)
|
2008-05-22 16:54:27 +00:00
|
|
|
{
|
2021-03-11 16:14:40 +00:00
|
|
|
profileMutex.lock();
|
|
|
|
|
|
2008-05-22 16:54:27 +00:00
|
|
|
ProfileMap::iterator pmi = m_profiles.find(id);
|
|
|
|
|
if (pmi != m_profiles.end()) {
|
|
|
|
|
++pmi->second.first;
|
2022-07-14 10:02:39 +01:00
|
|
|
pmi->second.second += us;
|
2008-05-22 16:54:27 +00:00
|
|
|
} else {
|
2022-07-14 10:02:39 +01:00
|
|
|
m_profiles[id] = TimePair(1, us);
|
2008-05-22 16:54:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WorstCallMap::iterator wci = m_worstCalls.find(id);
|
|
|
|
|
if (wci != m_worstCalls.end()) {
|
2022-07-14 10:02:39 +01:00
|
|
|
if (us > wci->second) wci->second = us;
|
2008-05-22 16:54:27 +00:00
|
|
|
} else {
|
2022-07-14 10:02:39 +01:00
|
|
|
m_worstCalls[id] = us;
|
2008-05-22 16:54:27 +00:00
|
|
|
}
|
2021-03-11 16:14:40 +00:00
|
|
|
|
|
|
|
|
profileMutex.unlock();
|
2008-05-22 16:54:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
Profiler::dump()
|
|
|
|
|
{
|
2012-09-09 16:57:42 +01:00
|
|
|
std::string report = getReport();
|
|
|
|
|
fprintf(stderr, "%s", report.c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string
|
|
|
|
|
Profiler::getReport()
|
|
|
|
|
{
|
2021-03-11 16:14:40 +00:00
|
|
|
profileMutex.lock();
|
|
|
|
|
|
2012-09-09 16:57:42 +01:00
|
|
|
static const int buflen = 256;
|
|
|
|
|
char buffer[buflen];
|
|
|
|
|
std::string report;
|
|
|
|
|
|
2008-05-22 16:54:27 +00:00
|
|
|
#ifdef PROFILE_CLOCKS
|
2012-09-09 16:57:42 +01:00
|
|
|
snprintf(buffer, buflen, "Profiling points [CPU time]:\n");
|
2008-05-22 16:54:27 +00:00
|
|
|
#else
|
2012-09-09 16:57:42 +01:00
|
|
|
snprintf(buffer, buflen, "Profiling points [Wall time]:\n");
|
2008-05-22 16:54:27 +00:00
|
|
|
#endif
|
2012-09-09 16:57:42 +01:00
|
|
|
report += buffer;
|
2008-05-22 16:54:27 +00:00
|
|
|
|
2022-07-14 09:42:10 +01:00
|
|
|
typedef std::multimap<double, const char *> TimeRMap;
|
2008-05-22 16:54:27 +00:00
|
|
|
typedef std::multimap<int, const char *> IntRMap;
|
|
|
|
|
TimeRMap totmap, avgmap, worstmap;
|
|
|
|
|
IntRMap ncallmap;
|
|
|
|
|
|
2022-07-14 10:02:39 +01:00
|
|
|
const unsigned char mu_s[] = { 0xce, 0xbc, 's', 0x0 };
|
|
|
|
|
|
2008-05-22 16:54:27 +00:00
|
|
|
for (ProfileMap::const_iterator i = m_profiles.begin();
|
|
|
|
|
i != m_profiles.end(); ++i) {
|
|
|
|
|
totmap.insert(TimeRMap::value_type(i->second.second, i->first));
|
|
|
|
|
avgmap.insert(TimeRMap::value_type(i->second.second /
|
|
|
|
|
i->second.first, i->first));
|
|
|
|
|
ncallmap.insert(IntRMap::value_type(i->second.first, i->first));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (WorstCallMap::const_iterator i = m_worstCalls.begin();
|
|
|
|
|
i != m_worstCalls.end(); ++i) {
|
|
|
|
|
worstmap.insert(TimeRMap::value_type(i->second, i->first));
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-09 16:57:42 +01:00
|
|
|
snprintf(buffer, buflen, "\nBy name:\n");
|
|
|
|
|
report += buffer;
|
|
|
|
|
|
|
|
|
|
typedef std::set<const char *, std::less<std::string> > StringSet;
|
|
|
|
|
|
|
|
|
|
StringSet profileNames;
|
|
|
|
|
for (ProfileMap::const_iterator i = m_profiles.begin();
|
|
|
|
|
i != m_profiles.end(); ++i) {
|
|
|
|
|
profileNames.insert(i->first);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (StringSet::const_iterator i = profileNames.begin();
|
|
|
|
|
i != profileNames.end(); ++i) {
|
|
|
|
|
|
|
|
|
|
ProfileMap::const_iterator j = m_profiles.find(*i);
|
|
|
|
|
if (j == m_profiles.end()) continue;
|
|
|
|
|
|
|
|
|
|
const TimePair &pp(j->second);
|
|
|
|
|
snprintf(buffer, buflen, "%s(%d):\n", *i, pp.first);
|
|
|
|
|
report += buffer;
|
2022-07-14 10:02:39 +01:00
|
|
|
snprintf(buffer, buflen, "\tReal: \t%12f %s \t[%f %s total]\n",
|
|
|
|
|
(pp.second / pp.first), mu_s,
|
|
|
|
|
(pp.second), mu_s);
|
2012-09-09 16:57:42 +01:00
|
|
|
report += buffer;
|
|
|
|
|
|
|
|
|
|
WorstCallMap::const_iterator k = m_worstCalls.find(*i);
|
|
|
|
|
if (k == m_worstCalls.end()) continue;
|
|
|
|
|
|
2022-07-14 10:02:39 +01:00
|
|
|
snprintf(buffer, buflen, "\tWorst:\t%14f %s/call\n", k->second, mu_s);
|
|
|
|
|
report += buffer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
snprintf(buffer, buflen, "\nBy total:\n");
|
|
|
|
|
report += buffer;
|
|
|
|
|
for (TimeRMap::const_iterator i = totmap.end(); i != totmap.begin(); ) {
|
|
|
|
|
--i;
|
|
|
|
|
snprintf(buffer, buflen, "%-40s %14f %s\n", i->second, i->first, mu_s);
|
|
|
|
|
report += buffer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
snprintf(buffer, buflen, "\nBy average:\n");
|
|
|
|
|
report += buffer;
|
|
|
|
|
for (TimeRMap::const_iterator i = avgmap.end(); i != avgmap.begin(); ) {
|
|
|
|
|
--i;
|
|
|
|
|
snprintf(buffer, buflen, "%-40s %14f %s\n", i->second, i->first, mu_s);
|
|
|
|
|
report += buffer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
snprintf(buffer, buflen, "\nBy worst case:\n");
|
|
|
|
|
report += buffer;
|
|
|
|
|
for (TimeRMap::const_iterator i = worstmap.end(); i != worstmap.begin(); ) {
|
|
|
|
|
--i;
|
|
|
|
|
snprintf(buffer, buflen, "%-40s %14f %s\n", i->second, i->first, mu_s);
|
|
|
|
|
report += buffer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
snprintf(buffer, buflen, "\nBy number of calls:\n");
|
|
|
|
|
report += buffer;
|
|
|
|
|
for (IntRMap::const_iterator i = ncallmap.end(); i != ncallmap.begin(); ) {
|
|
|
|
|
--i;
|
|
|
|
|
snprintf(buffer, buflen, "%-40s %14d\n", i->second, i->first);
|
2012-09-09 16:57:42 +01:00
|
|
|
report += buffer;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-11 16:14:40 +00:00
|
|
|
profileMutex.unlock();
|
|
|
|
|
|
2012-09-09 16:57:42 +01:00
|
|
|
return report;
|
2008-05-22 16:54:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Profiler::Profiler(const char* c) :
|
|
|
|
|
m_c(c),
|
|
|
|
|
m_ended(false)
|
|
|
|
|
{
|
2022-07-14 09:42:10 +01:00
|
|
|
m_start = std::chrono::steady_clock::now();
|
2008-05-22 16:54:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Profiler::~Profiler()
|
|
|
|
|
{
|
|
|
|
|
if (!m_ended) end();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
Profiler::end()
|
|
|
|
|
{
|
2022-07-14 09:42:10 +01:00
|
|
|
auto finish = std::chrono::steady_clock::now();
|
2022-07-14 10:02:39 +01:00
|
|
|
std::chrono::duration<double, std::micro> us = finish - m_start;
|
|
|
|
|
add(m_c, us.count());
|
2008-05-22 16:54:27 +00:00
|
|
|
m_ended = true;
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-17 13:01:21 +00:00
|
|
|
#else /* NO_TIMING */
|
|
|
|
|
|
|
|
|
|
#ifndef NO_TIMING_COMPLETE_NOOP
|
|
|
|
|
|
|
|
|
|
Profiler::Profiler(const char *) { }
|
|
|
|
|
Profiler::~Profiler() { }
|
|
|
|
|
void Profiler::end() { }
|
|
|
|
|
void Profiler::dump() { }
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
2008-05-22 16:54:27 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
}
|