7
    QElapsedTimer timer;
    timer.start();

    slowOperation1();

    qDebug() << "The slow operation took" << timer.elapsed() << "milliseconds";

http://doc.qt.io/qt-5/qelapsedtimer.html#invalidate

After qDebug() I would want to stop this timer. I can't see a stop function there, nor a single shot property.

What's the way out?

Aquarius_Girl
  • 21,790
  • 65
  • 230
  • 411

3 Answers3

12

You can't stop QElapsedTimer, because there is no timer. When you call method start(), QElapsedTimer saves the current time.

From qelapsedtimer_generic.cpp

void QElapsedTimer::start() Q_DECL_NOTHROW
{
    restart();
}

qint64 QElapsedTimer::restart() Q_DECL_NOTHROW
{
    qint64 old = t1;
    t1 = QDateTime::currentMSecsSinceEpoch();
    t2 = 0;
    return t1 - old;
}

When elapsed, it gets current time again, and calculate difference.

qint64 QElapsedTimer::elapsed() const Q_DECL_NOTHROW
{
    return QDateTime::currentMSecsSinceEpoch() - t1;
}

P.S. Specific realization is platform dependent: Windows, Unix, Mac

Meefte
  • 6,469
  • 1
  • 39
  • 42
1

QElapsedTimer will use the platform's monotonic reference clock in all platforms that support it. This has the added benefit that QElapsedTimer is immune to time adjustments, such as the user correcting the time. Also unlike QTime, QElapsedTimer is immune to changes in the timezone settings, such as daylight-saving periods. https://doc.qt.io/qt-5/qelapsedtimer.html#details

1

I needed an elapsed timer that wouldn't count the paused time, so here's what I came up with: ElapsedTimer.hpp:

#pragma once

#include <time.h>
#include <cstdio>
#include <cstdint>
#include <cstring>
#include <errno.h>

namespace your_namespace {

class ElapsedTimer {
public:
    ElapsedTimer();
    ~ElapsedTimer();
    
    void Continue();
    void Pause();
    int64_t elapsed_ms();
    
private:
    struct timespec start_ = {};
    int64_t worked_time_ = 0;
    
    /// CLOCK_MONOTONIC_COARSE is faster but less precise
    /// CLOCK_MONOTONIC_RAW is slower but more precise
    const clockid_t clock_type_ = CLOCK_MONOTONIC_RAW;
};
}

ElapsedTimer.cpp:

#include "ElapsedTimer.hpp"

namespace your_namespace {

ElapsedTimer::ElapsedTimer() {}
ElapsedTimer::~ElapsedTimer() {}

inline int64_t GetDiffMs(const timespec &end, const timespec &start) {
    return (end.tv_sec - start.tv_sec) * 1000L + (end.tv_nsec - start.tv_nsec) / 1000000L;
}

void ElapsedTimer::Continue()
{
    int status = clock_gettime(clock_type_, &start_);
    if (status != 0)
        printf("%s", strerror(errno));
}

int64_t ElapsedTimer::elapsed_ms()
{
    const bool paused = (start_.tv_sec == 0 && start_.tv_nsec == 0);
    if (paused)
        return worked_time_;
    
    struct timespec now;
    int status = clock_gettime(clock_type_, &now);
    if (status != 0)
        printf("%s", strerror(errno));
    
    const int64_t extra = GetDiffMs(now, start_);
    return worked_time_ + extra;
}

void ElapsedTimer::Pause() {
    struct timespec now;
    int status = clock_gettime(clock_type_, &now);
    if (status != 0)
        printf("%s", strerror(errno));
    
    worked_time_ += GetDiffMs(now, start_);
    start_ = {};
}
}

To be used as:

my_namespace::ElapsedTimer timer;
timer.Continue(); // starts recording the amount of time
timer.Pause();// stops recording time
///do something else
timer.Continue();// resumes recording time
/// and at any time call this to find out how many
/// ms passed excluding the paused time:
int64_t passed_ms = timer.elapsed_ms();
nicknorton
  • 63
  • 5