HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Stopwatch template

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
stopwatchtemplatestackoverflow

Problem

It's often useful to be able to time code, for instance, to evaluate alternative approaches to the same problem. Because this is a thing I use frequently, I have created this Stopwatch templated class that I'd like for you all to review. Unlike some other recent code, this class is intended to be cross-platform and relies only on a working implementation of the std::chrono utilities in C++11.

Specifically, does the interface make sense? Could the code be improved? Also, I have thought it might be nice to provide some kind of a "units" function to return, say, a std::string containing "ms" if TimeT is set to std::chrono::milliseconds but ultimately decided against complicating the interface. I'd be open to comments on that decision as well.

stopwatch.h

#ifndef STOPWATCH_H
#define STOPWATCH_H
#include 

template
class Stopwatch
{
private:
    std::chrono::time_point _start, _end;
public:
    Stopwatch();
    void start();
    DurationT restart();
    DurationT stop();
    DurationT elapsed() const;
};

template
Stopwatch::Stopwatch() 
{ 
    start(); 
}

template
void Stopwatch::start() 
{ 
    _start = _end = ClockT::now(); 
}

template
DurationT Stopwatch::stop() 
{ 
    _end = ClockT::now(); 
    return elapsed(); 
}

template
DurationT Stopwatch::restart()
{ 
    DurationT ret = stop();
    start();
    return ret;
}

template
DurationT Stopwatch::elapsed() const
{ 
    auto delta = std::chrono::duration_cast(_end-_start); 
    return delta.count(); 
}
#endif


stoptest.cpp

#include 
#include 
#include "stopwatch.h"

int main()
{
    const int iterations = 1000000;
    double sqrtsum = 0;
    Stopwatch<> sw;
    for (int i=0; i<iterations; ++i)
        sqrtsum += sqrt(i);
    std::cout << "calculated " << sqrtsum << " in " << sw.restart() << " us\n";
    sqrtsum = 0;
    for (int i=0; i<iterations; ++i)
        sqrtsum += pow(i,0.5);
    std::cout << "calculated " << sqrtsum << " in " << sw.stop() << " us\n";
}


A few words about u

Solution

I would like this interface:

StopWatch    sw;

SomeTimeType   time = sw.time([](){
    for (int i=0; i<iterations; ++i)
         sqrtsum += sqrt(i);
});

std::cout << "It took: " << time << " Units\n";


I don't like the interface as it stands because you can call the functions in any order (which makes no sense). The interface should be designed so you can not call the functions in the wrong order. Which points at a design that does not involve explicit functions calls but a more declarative approach.

DurationT restart();        // Probably need to check the documentation on what that means.

DurationT elapsed() const;  // What happens if I call this on a currently running watch?
                            // I would still expect it to give me the current elapsed time
                            // but currently it return 0

Code Snippets

StopWatch    sw;

SomeTimeType   time = sw.time([](){
    for (int i=0; i<iterations; ++i)
         sqrtsum += sqrt(i);
});

std::cout << "It took: " << time << " Units\n";
DurationT restart();        // Probably need to check the documentation on what that means.

DurationT elapsed() const;  // What happens if I call this on a currently running watch?
                            // I would still expect it to give me the current elapsed time
                            // but currently it return 0

Context

StackExchange Code Review Q#58055, answer score: 8

Revisions (0)

No revisions yet.