Отримати витрачений час у Qt


74

Я шукаю еквівалент в Qt до GetTickCount()

Щось, що дозволить мені виміряти час, необхідний для запуску сегмента коду, як у:

uint start = GetTickCount();
// do something..
uint timeItTook = GetTickCount() - start;

будь-які пропозиції?

Відповіді:


94

Як щодо QTime? Залежно від вашої платформи, вона повинна мати точність 1 мілісекунду. Код буде виглядати приблизно так:

QTime myTimer;
myTimer.start();
// do something..
int nMilliseconds = myTimer.elapsed();

2
На моїй віртуальній машині WinXP, здається, точність лише 10 мс - може хтось підтвердити / спростувати це? Я отримую значення 0, 10 і 20 для операції, яку тестую.
Уілл Бікфорд,

4
Windows не такий точний, як UNIX-подібна ОС при хронометражі.
Nathan Moos

1
IIRC, у Windows XP стандартна роздільна здатність системного годинника за замовчуванням становить 15 мс, але при деяких простих викликах вінапі, що залежать від Windows, ви все одно можете отримати кращу роздільну здатність, якщо на материнській платі є лише
RMSC

6
QTime не дає часу процесору. Це дає загальний реальний час, а це означає, що ви також вимірюєте час, зайнятий усіма іншими процесами. Тому це не дуже корисно для вимірювання часу виконання коду.
Нікос К.

4
Це тонка і страшна помилка, яка чекає, що станеться. На це впливає системний годинник. Не дай Бог, щоб переходив на літній час, коли працює ваш таймер.
andrewrk

127

Я думаю, що це, мабуть, краще використовувати, QElapsedTimerоскільки саме тому клас існує в першу чергу. Він був представлений з Qt 4.7. Зверніть увагу, що це також враховується до зміни годинника системи.

Приклад використання:

#include <QDebug>
#include <QElapsedTimer>
...
...
QElapsedTimer timer;
timer.start();
slowOperation();  // we want to measure the time of this slowOperation()
qDebug() << timer.elapsed();

40

Навіть якщо перша відповідь була прийнята, решта людей, які читали відповіді, повинні врахувати sivabudhпропозицію.
QElapsedTimerтакож можна використовувати для обчислення часу в наносекундах.
Приклад коду:

QElapsedTimer timer;
qint64 nanoSec;
timer.start();
//something happens here
nanoSec = timer.nsecsElapsed();
//printing the result(nanoSec)
//something else happening here
timer.restart();
//some other operation
nanoSec = timer.nsecsElapsed();

2
Знову ж таки: це вимірює реальний час, а не витрачений процесором час.
Нікос К.

Він обчислює його, приймаючи кількість галочок процесора, яку споживає програма, і множить на кількість наносекунд на тик. Він вимірює час процесора, витрачений процесом.
Ліліан А. Морару

Він вимірює час, що минув з того часу start(), а не час, витрачений процесом. Це таймер реального часу. Коли процес отримує перевагу (через багатозадачність), час продовжує проходити, і QElapsedTimer також вимірюватиме це. QElapsedTimer був би майже марним, якщо б припинив вимірювати час, коли процес випереджається.
Nikos C.

@NikosC. З блогу Qt "Qt має ряд таймерів, але найбільш корисним для порівняльного тесту є QElapsedTimer", тоді "QElapsedTimer буде використовувати найточніший доступний годинник. Однак це також означає, що фактична роздільна здатність і точність таймера можуть сильно відрізнятися між системами. ". Де він вибирає найбільш точний годинник із цих: qt-project.org/doc/qt-5/qelapsedtimer.html#ClockType-enum .
Ліліан А. Морару

2

Якщо ви хочете використовувати QElapsedTimer, вам слід розглянути накладні витрати на цей клас.

Наприклад, на моїй машині працює такий код:

static qint64 time = 0;
static int count = 0;
QElapsedTimer et;
et.start();
time += et.nsecsElapsed();
if (++count % 10000 == 0)
    qDebug() << "timing:" << (time / count) << "ns/call";

дає мені цей результат:

timing: 90 ns/call 
timing: 89 ns/call 
...

Ви повинні виміряти це для себе і поважати накладні витрати за ваші терміни.


1
Я згоден. Я спробував QElapsedTimer. Здається, це має певні накладні витрати, пов'язані з використанням класу. Але дуже незначні. Різниця не така вже й велика. Але QTime, здавалося, дав мені трохи швидший час виконання. Я виміряв код подрібнення кількості 4 методів (3 рази з QTime і 3 з QElapsedTimer). Таймер QElapsed вимірював у середньому 8,046 секунди, а QTime - 8,016 секунди, різниця становила 30 мс. Це не важливо для більшості цілей, але, можливо, це для абсолютної точності. На ньому працював 32-розрядний QT 5.3.1 на 64-розрядному ПК Windows 7 Intel i5.
te7

1
Дивіться тему тут qtcentre.org/threads/…
te7

2

Розширюючи попередні відповіді, ось макрос, який робить все за вас.

#include <QDebug>
#include <QElapsedTimer>
#define CONCAT_(x,y) x##y
#define CONCAT(x,y) CONCAT_(x,y)

#define CHECKTIME(x)  \
    QElapsedTimer CONCAT(sb_, __LINE__); \
    CONCAT(sb_, __LINE__).start(); \
    x \
    qDebug() << __FUNCTION__ << ":" << __LINE__ << " Elapsed time: " <<  CONCAT(sb_, __LINE__).elapsed() << " ms.";

І тоді ви можете просто використовувати як:

CHECKTIME(
    // any code
    for (int i=0; i<1000; i++)
    {
       timeConsumingFunc();
    }
)

вихід:

onSpeedChanged: 102 Минув час: 2 мс.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.