当您想获取有关特定代码路径的性能数据时,您使用什么方法?
最佳答案
这种方法有一些局限性,但我仍然觉得它非常有用。我会预先列出限制(我知道),让任何想要使用它的人自行承担风险。
- 我发布的原始版本夸大了递归调用所花费的时间(正如答案的评论中所指出的那样)。
- 它不是线程安全的,在我添加代码以忽略递归之前它不是线程安全的,现在它的线程安全性更差了。
- 虽然调用多次(数百万次)会非常有效,但它会对结果产生可衡量的影响,因此您测量的范围将比您不测量的范围花费更长的时间。
当手头的问题不能证明分析我的所有代码是合理的,或者我从分析器获得一些我想要验证的数据时,我会使用这个类。基本上它总结了您在特定 block 中花费的时间,并在程序结束时将其输出到调试流(可通过 DbgView 查看),包括代码执行的次数(当然还有平均花费的时间) )。
#pragma once
#include <tchar.h>
#include <windows.h>
#include <sstream>
#include <boost/noncopyable.hpp>
namespace scope_timer {
class time_collector : boost::noncopyable {
__int64 total;
LARGE_INTEGER start;
size_t times;
const TCHAR* name;
double cpu_frequency()
{ // cache the CPU frequency, which doesn't change.
static double ret = 0; // store as double so devision later on is floating point and not truncating
if (ret == 0) {
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
ret = static_cast<double>(freq.QuadPart);
}
return ret;
}
bool in_use;
public:
time_collector(const TCHAR* n)
: times(0)
, name(n)
, total(0)
, start(LARGE_INTEGER())
, in_use(false)
{
}
~time_collector()
{
std::basic_ostringstream<TCHAR> msg;
msg << _T("scope_timer> ") << name << _T(" called: ");
double seconds = total / cpu_frequency();
double average = seconds / times;
msg << times << _T(" times total time: ") << seconds << _T(" seconds ")
<< _T(" (avg ") << average <<_T(")\n");
OutputDebugString(msg.str().c_str());
}
void add_time(__int64 ticks)
{
total += ticks;
++times;
in_use = false;
}
bool aquire()
{
if (in_use)
return false;
in_use = true;
return true;
}
};
class one_time : boost::noncopyable {
LARGE_INTEGER start;
time_collector* collector;
public:
one_time(time_collector& tc)
{
if (tc.aquire()) {
collector = &tc;
QueryPerformanceCounter(&start);
}
else
collector = 0;
}
~one_time()
{
if (collector) {
LARGE_INTEGER end;
QueryPerformanceCounter(&end);
collector->add_time(end.QuadPart - start.QuadPart);
}
}
};
}
// Usage TIME_THIS_SCOPE(XX); where XX is a C variable name (can begin with a number)
#define TIME_THIS_SCOPE(name) \
static scope_timer::time_collector st_time_collector_##name(_T(#name)); \
scope_timer::one_time st_one_time_##name(st_time_collector_##name)
关于c++ - 快速而肮脏的方式来分析你的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61278/