ATLAS Offline Software
Loading...
Searching...
No Matches
columnar::TestUtils::Benchmark Class Referencefinal

this is a simple benchmarking helper class wrapping timers from std::chrono More...

#include <Benchmark.h>

Collaboration diagram for columnar::TestUtils::Benchmark:

Public Member Functions

 Benchmark (const std::string &val_name="", unsigned val_batchSize=1)
 ~Benchmark ()
void setSilence ()
std::optional< float > getEntryTime (float emptyTime) const
auto getTotalTime () const
void startTimer ()
void stopTimer ()

Private Attributes

std::string m_name
std::chrono::time_point< std::chrono::high_resolution_clock > m_start
std::chrono::high_resolution_clock::duration m_ticks {}
 accumulated time m_ticks
std::uint64_t m_count = 0
 the number of times the timer has been started
unsigned m_batchSize = 1
 the number of calls per batch
bool m_silence = false
 whether to suppress output

Detailed Description

this is a simple benchmarking helper class wrapping timers from std::chrono

Essentially this just takes care of all the bookkeeping around starting and stopping the timer, accumulating the total time, and computing the average time per entry. The compiler should (hopefully) inline the performance sensitive parts to avoid the overhead. This allows to perform fine-grained and precise measurements of various parts of the code and is extensively used in the PHYSLITE tests.

By default this will just print the average time per entry in the destructor, however this is not scalable to large number of separate benchmarks. So in general you should set it to silent and use getEntryTime to retrieve the time instead. At some point I may also remove the automatic printing altogether and make that the default behavior.

This also allows to specify a batch size, which is useful when we process multiple events at once and want to compare to time per event with other batch sizes or single-event processing.

Warning
There is a non-negligible overhead to starting and stopping the timer. So for one you should not use this in production code. For another you should measure the overhead with a separate benchmark instance that starts and stops immediately and subtract that from the measured time (getEntryTime provides that option).

Definition at line 50 of file Benchmark.h.

Constructor & Destructor Documentation

◆ Benchmark()

columnar::TestUtils::Benchmark::Benchmark ( const std::string & val_name = "",
unsigned val_batchSize = 1 )
inline

Public Members

Definition at line 56 of file Benchmark.h.

57 : m_name (val_name), m_batchSize (val_batchSize)
58 {
59 if (m_name.empty())
60 m_silence = true;
61 }
unsigned m_batchSize
the number of calls per batch
Definition Benchmark.h:114
bool m_silence
whether to suppress output
Definition Benchmark.h:117

◆ ~Benchmark()

columnar::TestUtils::Benchmark::~Benchmark ( )
inline

Definition at line 63 of file Benchmark.h.

64 {
65 if (m_count > 0 && !m_silence)
66 std::cout << m_name << ": " << std::chrono::duration<std::uint64_t,std::nano> (m_ticks) / (m_count * m_batchSize) << std::endl;
67 }
std::uint64_t m_count
the number of times the timer has been started
Definition Benchmark.h:111
std::chrono::high_resolution_clock::duration m_ticks
accumulated time m_ticks
Definition Benchmark.h:108

Member Function Documentation

◆ getEntryTime()

std::optional< float > columnar::TestUtils::Benchmark::getEntryTime ( float emptyTime) const
inline

Definition at line 74 of file Benchmark.h.

75 {
76 if (m_count == 0)
77 return std::nullopt;
78 return static_cast<float>((std::chrono::duration<float,std::nano> (m_ticks) / (m_count * m_batchSize)) / std::chrono::duration<float,std::nano> (1))-emptyTime/m_batchSize;
79 }

◆ getTotalTime()

auto columnar::TestUtils::Benchmark::getTotalTime ( ) const
inline

Definition at line 81 of file Benchmark.h.

82 {
83 return m_ticks;
84 }

◆ setSilence()

void columnar::TestUtils::Benchmark::setSilence ( )
inline

Definition at line 69 of file Benchmark.h.

70 {
71 m_silence = true;
72 }

◆ startTimer()

void columnar::TestUtils::Benchmark::startTimer ( )
inline

Definition at line 86 of file Benchmark.h.

87 {
88 m_start = std::chrono::high_resolution_clock::now();
89 }
std::chrono::time_point< std::chrono::high_resolution_clock > m_start
Definition Benchmark.h:105

◆ stopTimer()

void columnar::TestUtils::Benchmark::stopTimer ( )
inline

Definition at line 91 of file Benchmark.h.

92 {
93 m_ticks += std::chrono::high_resolution_clock::now() - m_start;
94 m_count += 1;
95 }

Member Data Documentation

◆ m_batchSize

unsigned columnar::TestUtils::Benchmark::m_batchSize = 1
private

the number of calls per batch

Definition at line 114 of file Benchmark.h.

◆ m_count

std::uint64_t columnar::TestUtils::Benchmark::m_count = 0
private

the number of times the timer has been started

Definition at line 111 of file Benchmark.h.

◆ m_name

std::string columnar::TestUtils::Benchmark::m_name
private

Private Members

Definition at line 103 of file Benchmark.h.

◆ m_silence

bool columnar::TestUtils::Benchmark::m_silence = false
private

whether to suppress output

Definition at line 117 of file Benchmark.h.

◆ m_start

std::chrono::time_point<std::chrono::high_resolution_clock> columnar::TestUtils::Benchmark::m_start
private

Definition at line 105 of file Benchmark.h.

◆ m_ticks

std::chrono::high_resolution_clock::duration columnar::TestUtils::Benchmark::m_ticks {}
private

accumulated time m_ticks

Definition at line 108 of file Benchmark.h.

108{};

The documentation for this class was generated from the following file: