Belle II Software  release-08-01-10
TimeIt.h
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 #pragma once
9 
10 #ifdef HAS_CALLGRIND
11 #include <valgrind/callgrind.h>
12 #endif
13 
14 #include <framework/logging/Logger.h>
15 
16 #include <vector>
17 #include <functional>
18 #include <chrono>
19 #include <numeric>
20 
21 namespace Belle2 {
26  namespace TrackFindingCDC {
27 
29  class TimeItResult {
30  public:
32  explicit TimeItResult(const std::vector<std::chrono::duration<double> >& timeSpans) :
33  m_timeSpans(timeSpans)
34  {}
35 
37  double getSeconds(size_t iExecution) const
38  {
39  return m_timeSpans.at(iExecution).count();
40  }
41 
43  double getAverageSeconds() const
44  {
45  std::chrono::duration<double> sumTimeSpan =
46  std::accumulate(m_timeSpans.begin(), m_timeSpans.end(), std::chrono::duration<double>());
47 
48  std::chrono::duration<double> avgTimeSpan = sumTimeSpan / m_timeSpans.size();
49  return avgTimeSpan.count();
50  }
51 
53  size_t getNExecutions() const
54  { return m_timeSpans.size(); }
55 
57  void printSummary() const
58  {
59  B2INFO("First execution took " << getSeconds(0) << " seconds ");
60  B2INFO("On average execution took " << getAverageSeconds() << " seconds " <<
61  "in " << getNExecutions() << " executions.");
62  }
63 
64  private:
66  std::vector<std::chrono::duration<double> > m_timeSpans;
67 
68  };
69 
71  const std::function<void()> doNothing = []() {};
72 
74  template<class AFunction >
75  TimeItResult
76  timeIt(size_t nExecutions,
77  bool activateCallgrind,
78  const AFunction& function,
79  const std::function<void()>& setUp = doNothing,
80  const std::function<void()>& tearDown = doNothing)
81  {
82  using namespace std::chrono;
83 
84  std::vector<duration<double>> timeSpans;
85  timeSpans.reserve(nExecutions);
86 
87  for (std::size_t iExecution = 0; iExecution < nExecutions; ++iExecution) {
88  setUp();
89 
90  auto now = std::chrono::high_resolution_clock::now();
91 
92  if (activateCallgrind) {
93 #ifdef HAS_CALLGRIND
94  CALLGRIND_START_INSTRUMENTATION;
95 #endif
96  }
97 
98  function();
99 
100  if (activateCallgrind) {
101 #ifdef HAS_CALLGRIND
102  CALLGRIND_STOP_INSTRUMENTATION;
103 #endif
104  }
105 
106  auto later = std::chrono::high_resolution_clock::now();
107 
108  duration<double> timeSpan = duration_cast<duration<double> >(later - now);
109  timeSpans.push_back(timeSpan);
110  tearDown();
111  }
112  return TimeItResult(timeSpans);
113  }
114  }
116 }
Class to capture the time a repeated execution took.
Definition: TimeIt.h:29
void printSummary() const
Print a summary of the collected time to the console.
Definition: TimeIt.h:57
size_t getNExecutions() const
Get number of executions.
Definition: TimeIt.h:53
double getSeconds(size_t iExecution) const
Get the time of the individual executtions.
Definition: TimeIt.h:37
double getAverageSeconds() const
Get the average execution time.
Definition: TimeIt.h:43
TimeItResult(const std::vector< std::chrono::duration< double > > &timeSpans)
Constructor from a series of timings.
Definition: TimeIt.h:32
std::vector< std::chrono::duration< double > > m_timeSpans
Memory for the time spans a repeated execution took.
Definition: TimeIt.h:66
Abstract base class for different kinds of events.