]> git.lyx.org Git - lyx.git/commitdiff
A poor man's profiler.
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Thu, 21 Mar 2013 11:14:21 +0000 (12:14 +0100)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Fri, 22 Mar 2013 09:30:48 +0000 (10:30 +0100)
The use of this profiler is trivial:

 * #include <support/pmprof.h>

 * in the block one wants to profile, add
   PROFILE_THIS_BLOCK(some_identifier)

 * At the end of the execution, statistics will be sent to standard error.

src/support/Makefile.am
src/support/pmprof.h [new file with mode: 0644]

index a537ff8da5b7c6e73d1a354ae823304131173943..5ab3ef99eecb5c2204ab08099743ac19776fafdc 100644 (file)
@@ -83,6 +83,7 @@ liblyxsupport_a_SOURCES = \
        Package.cpp \
        Package.h \
        ProgressInterface.h \
+       pmprof.h \
        qstring_helpers.cpp \
        qstring_helpers.h \
        regex.h \
diff --git a/src/support/pmprof.h b/src/support/pmprof.h
new file mode 100644 (file)
index 0000000..f1506ec
--- /dev/null
@@ -0,0 +1,88 @@
+// -*- C++ -*-
+/* \file pmprof.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Jean-Marc Lasgouttes
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef PMPROF_H
+#define PMPROF_H
+
+#include <sys/time.h>
+#include <iostream>
+
+/** How to use this trivial profiler:
+ *
+ * * at the beginning of the interesting block, just add:
+ *   PROFILE_THIS_BLOCK(some_identifier);
+ *
+ * * when the program ends, statistics will be sent to standard error, like:
+ *
+ *   ##### some_identifier: 6.48475usec, count=25405
+ *
+ * The code measured by the profiler corresponds to the lifetime of a
+ * local variable declared by the PROFILE_THIS_BLOCK macro.
+ */
+
+/* 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) {};
+
+       ~PMProfStat() {
+               if (count_>0)
+                 std::cerr << "##### " << name_ << ": "
+                           << 1.0 * (sec_ * 1000000 + usec_)/ count_
+                           << "usec, count=" << count_ << std::endl;
+       }
+
+       void add(const long long s, const long long u) {
+               sec_ += s;
+               usec_ += u;
+               count_++;
+       }
+
+private:
+       char const * name_;
+       long long sec_, usec_;
+       unsigned long long count_;
+};
+
+
+/* Helper class which gathers data at the end of the scope. One
+ * instance of this one should be created at each execution of the
+ * block. At the end of the block, it sends statistics to the static
+ * PMProfStat object.
+ */
+class PMProfInstance {
+public:
+       PMProfInstance(PMProfStat * stat) : stat_(stat)
+       {
+               gettimeofday(&before_, 0);
+       }
+
+       ~PMProfInstance() {
+               gettimeofday(&after_, 0);
+               stat_->add(after_.tv_sec - before_.tv_sec,
+                          after_.tv_usec - before_.tv_usec);
+       }
+
+private:
+       timeval before_, after_;
+       PMProfStat * stat_;
+};
+
+
+#define PROFILE_THIS_BLOCK(a) \
+       static PMProfStat PMPS_##a(#a);\
+       PMProfInstance PMPI_##a(&PMPS_##a)
+
+
+#endif