X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fsupport%2Fpmprof.h;h=fe5ab7a4fdde0466c3460e8acb7f021c96221bf6;hb=77ab3017d0bc759ff8f69cec5cb5b7d9eae122c6;hp=f1506ec222485f9c3aed8287b7b2a40c21113cb3;hpb=4663618cfd774f974bbbb8f0859970907300c0b8;p=lyx.git diff --git a/src/support/pmprof.h b/src/support/pmprof.h index f1506ec222..fe5ab7a4fd 100644 --- a/src/support/pmprof.h +++ b/src/support/pmprof.h @@ -8,16 +8,12 @@ * Full author contact details are available in file CREDITS. */ -#ifndef PMPROF_H -#define PMPROF_H - -#include -#include - /** How to use this trivial profiler: * * * at the beginning of the interesting block, just add: - * PROFILE_THIS_BLOCK(some_identifier); + * PROFILE_THIS_BLOCK(some_identifier) + * + * A trailing semicolon can be added at your discretion. * * * when the program ends, statistics will be sent to standard error, like: * @@ -25,22 +21,125 @@ * * The code measured by the profiler corresponds to the lifetime of a * local variable declared by the PROFILE_THIS_BLOCK macro. + * + * Some examples of profiling scope: In the snippets below, c1, c2... + * designate code chunks, and the identifiers of profiling blocks are + * chosen to reflect what they count. + * + * { + * c1 + * PROFILE_THIS_BLOCK(c2) + * c2 + * } + * + * + * { + * PROFILE_THIS_BLOCK(c1_c2) + * c1 + * PROFILE_THIS_BLOCK(c2) + * c2 + * } + * + * + * { + * { + * PROFILE_THIS_BLOCK(c1) + * c1 + * } + * PROFILE_THIS_BLOCK(c2) + * c2 + * } + * + * + * { + * PROFILE_THIS_BLOCK(c1_c2_c3) + * c1 + * { + * PROFILE_THIS_BLOCK(c2) + * c2 + * } + * c3 + * } + * + * Influence of identifier names: they are mainly used for display + * purpose, but the same name should not be used twice in the same + * scope. + * + * { + * PROFILE_THIS_BLOCK(foo) + * c1 + * PROFILE_THIS_BLOCK(foo) // error: identifier clash + * c2 + * } + * + * In the example below, c1+c2 and c2 are counted separately, but in + * the output, both are confusingly labelled `foo'. + * + * { + * PROFILE_THIS_BLOCK(foo) + * c1 + * { + * PROFILE_THIS_BLOCK(foo) // error: identifier clash + * c2 + * } + * } + + */ + +#ifndef PMPROF_H +#define PMPROF_H + +#ifdef _WIN32 +#include +#else +#include +#endif + +#include +#include + + +#if defined(__GNUG__) && defined(_GLIBCXX_DEBUG) +#error Profiling is not usable when run-time debugging is in effect +#endif + +#ifdef _WIN32 +/* This function does not really returns the "time of day", + * but it will suffice to evaluate elapsed times. */ +int gettimeofday(struct timeval * tv, struct timezone * /*tz*/) +{ + LARGE_INTEGER frequency, t; + QueryPerformanceFrequency(&frequency); + QueryPerformanceCounter(&t); + + tv->tv_sec = long(t.QuadPart / frequency.QuadPart); + tv->tv_usec = long((1000000.0 * (t.QuadPart % frequency.QuadPart)) / frequency.QuadPart); + return 0; +} + +#endif // _WIN32 /* Helper class for gathering data. Instantiate this as a static * variable, so that its destructor will be executed when the program * ends. */ + class PMProfStat { public: PMProfStat(char const * name) - : name_(name), sec_(0), usec_(0), count_(0) {}; + : name_(name), sec_(0), usec_(0), count_(0) {} ~PMProfStat() { - if (count_>0) - std::cerr << "##### " << name_ << ": " - << 1.0 * (sec_ * 1000000 + usec_)/ count_ - << "usec, count=" << count_ << std::endl; + if (count_>0) { + double total = 0.001 * (sec_ * 1000000 + usec_); + std::cerr << std::fixed << std::setprecision(2) + << "#pmprof# " << name_ << ": " + << total / count_ + << "msec, count=" << count_ + << ", total=" << total << "msec" + << std::endl; + } } void add(const long long s, const long long u) { @@ -82,7 +181,7 @@ private: #define PROFILE_THIS_BLOCK(a) \ static PMProfStat PMPS_##a(#a);\ - PMProfInstance PMPI_##a(&PMPS_##a) + PMProfInstance PMPI_##a(&PMPS_##a); #endif