The following is a short timing utility I've written for a larger project that I'm working on. The larger project is designed to be called (via ffi) from a Scala/Java codebase, which makes using standard profiling tools somewhat difficult - especially at the granularity that we want.
Essentially, we want to be able to track roughly how long a few key functions are taking, and we want a low overhead way of doing so. The following code is my implementation of a timer class that starts timing when constructed, and then finishes (and reports data) when it destructs.
I chose this way of doing things as it gives quite a succinct way of benchmarking a function, take for example, a function foo
that we wanted to benchmark, all we would have to do is the following:
void foo(/*some arguments*/) {
auto timer = CSDSTimer("foo", "example");
/*do some more stuff*/
}
I think this is quite a nice solution, but I'd be interested in feedback on my implementation, especially of my handling of streams, and whether there's any way to set the stream statically (see the commented out code).
Thanks!
#pragma once
#include <chrono>
#include <ctime>
#include <iostream>
class CSDSTimer {
public:
// Construct and start the timer
CSDSTimer(std::string name, std::string context = "global",
std::ostream &stream = std::cout)
: _name(name), _context(context), _default_str(&stream) {
_start = std::chrono::system_clock::now();
}
// Destruct and stop the timer, reporting the elapseed time
~CSDSTimer() {
_end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = _end - _start;
*_default_str << "PROFILING_DATUM(\"" << _name << "\", \"" << _context
<< "\", " << elapsed_seconds.count() * 1000 << ", \"C++\")"
<< std::endl;
}
// static void SetStream(std::ostream &str) { _default_str = &str; }
private:
std::string _name;
std::string _context;
std::chrono::time_point<std::chrono::system_clock> _start, _end;
std::ostream *_default_str;
// static std::ostream *_default_str;
};
system_clock
instead of the possibly more accuratehigh_resolution_clock
? And why do you calculateelapsed_seconds
as seconds, but manually convert it to milliseconds for output (you could do the calculations for milliseconds directly, which might be more accurate b/c of floating point weirdness)? \$\endgroup\$