Як розрахувати різницю в часі в C ++


95

Який найкращий спосіб розрахувати різницю в часі в C ++? Я приурочую швидкість виконання програми, тому мене цікавлять мілісекунди. А ще краще, секунди мілісекунди ..

Прийнята відповідь працює, але має включати ctime або time.h, як зазначено в коментарях.


Дупе, але зараз не може зв’язати
Роберт Гулд,

2
Голосування для закриття було занадто мало, занадто пізно. Я отримав робочу відповідь. Хороша спроба. До речі, я також не міг знайти посилання.
Джек БеНімбл

Це для вікон? потім спробуйте GetTickCount (Windows API)
aJ.

5
Роберт: На щастя, тому що нова публікація дозволила ще кілька відповідей, одну з яких я вибрав. Серйозно, я ставлю під сумнів цінність закриття дублікату. Що, якби деякі рішення не були згадані в першому? Нові технології розроблені? Не можете знайти через різні заголовки?
Джек БеНімбл

2
@JackBeNimble, який був на прийомі в декількох "дупках", які не були точно дурнями (можливо, люди, які, можливо, швидко читають питання та позначають його, оскільки це звучить схоже на інше питання), я категорично погоджуюсь з Вашою думкою ... ймовірно, пункт для обміну мета
стеками

Відповіді:


123

Див. std::clock()Функцію.

const clock_t begin_time = clock();
// do something
std::cout << float( clock () - begin_time ) /  CLOCKS_PER_SEC;

Якщо ви хочете розрахувати час виконання для себе (не для користувача), краще це зробити за допомогою тиків годинника (не секунд).

EDIT:
файли відповідальних заголовків - <ctime>або<time.h>


4
Майте на увазі, що навіть якщо clock () повертає кількість мілісекунд, точність clock () може бути набагато гіршою, ніж це. Екземпляр Fir в Windows, точність функції clock () становить приблизно 40 мс.
Джон Дайблінг,

2
Я спробував це на Mac 10.7. мій додаток виконує файл розміром 100 Мб за 15 секунд, але час різниці повідомляє 61 секунду. Не багато користі. Я думаю, що час (), мабуть, кращий.
Miek

5
clock()повертає витрачений процесором час. Отже, якщо паралельно запускати програму, час, повернутий функцією, буде накопиченим часом, витраченим на всі центральні процесори, а не часом, що минув cplusplus.com/reference/ctime/clock
Ameer Jewdaki

3
Ця відповідь вводить в оману, оскільки відображає час процесора, а не фактичний час настінного годинника.
Ультрафіолет

1
Тут я повинен погодитися з "Ультрафіолетом", оскільки використання процесорного часу для вимірювання швидкості програми здається неправильним. OP повинен позначити це як правильну відповідь. ІМО ви повинні використовувати станд :: хроно :: steady_clock :: зараз () , як описано кілька варіантів відповідей в наступній нитки stackoverflow.com/questions/2808398/easily-measure-elapsed-time
arunsun

37

якщо ви використовуєте c ++ 11, ось проста обгортка (див. цей суть ):

#include <iostream>
#include <chrono>

class Timer
{
public:
    Timer() : beg_(clock_::now()) {}
    void reset() { beg_ = clock_::now(); }
    double elapsed() const { 
        return std::chrono::duration_cast<second_>
            (clock_::now() - beg_).count(); }

private:
    typedef std::chrono::high_resolution_clock clock_;
    typedef std::chrono::duration<double, std::ratio<1> > second_;
    std::chrono::time_point<clock_> beg_;
};

Або для c ++ 03 на * nix:

#include <iostream>
#include <ctime>

class Timer
{
public:
    Timer() { clock_gettime(CLOCK_REALTIME, &beg_); }

    double elapsed() {
        clock_gettime(CLOCK_REALTIME, &end_);
        return end_.tv_sec - beg_.tv_sec +
            (end_.tv_nsec - beg_.tv_nsec) / 1000000000.;
    }

    void reset() { clock_gettime(CLOCK_REALTIME, &beg_); }

private:
    timespec beg_, end_;
};

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

int main()
{
    Timer tmr;
    double t = tmr.elapsed();
    std::cout << t << std::endl;

    tmr.reset();
    t = tmr.elapsed();
    std::cout << t << std::endl;
    return 0;
}

2
Іншим варіантом було б використовувати boost :: chrono замість простору імен C ++ 11 STL std :: chrono. Дякуємо за ваш код.
Didac Perez Parera

Обережно: це не спрацює, якщо користувач змінює час між Timer()викликом elapsed()if !std::chrono::high_resolution_clock::is_steady- що має місце в Linux!
jhasse

30

Я б серйозно задумався про використання Boost, зокрема boost :: posix_time :: ptime і boost :: posix_time :: time_duration (на http://www.boost.org/doc/libs/1_38_0/doc/html/date_time/posix_time .html ).

Це крос-платформний, простий у використанні, і, на мій досвід, забезпечує найвищий рівень роздільної здатності в часі, яку забезпечує операційна система. Можливо, також дуже важливий; він забезпечує декілька дуже приємних операторів вводу-виводу.

Щоб використовувати його для обчислення різниці у виконанні програми (до мікросекунд; можливо, надмірного), це виглядатиме приблизно так [браузер написаний, не перевірений]:

ptime time_start(microsec_clock::local_time());
//... execution goes here ...
ptime time_end(microsec_clock::local_time());
time_duration duration(time_end - time_start);
cout << duration << '\n';

3
Але boost local_time () не є монотонним, тому його не слід використовувати для вимірювання проміжків часу. Я не знайшов способу отримати доступ до монотонного часу від Boost.
gatopeich

27

Я додав цю відповідь, щоб пояснити, що прийнята відповідь показує час процесора, який, можливо, не той час, який ви бажаєте. Оскільки згідно з посиланням , є час процесора та час настінного годинника . Час настінного годинника - це час, який показує фактично минулий час, незалежно від будь-яких інших умов, таких як процесор, спільний для інших процесів. Наприклад, я використовував декілька процесорів для виконання певного завдання, і час роботи процесора був високим 18 с, де насправді потрібно фактично 2 с .

Щоб отримати фактичний час, який ви робите,

#include <chrono>

auto t_start = std::chrono::high_resolution_clock::now();
// the work...
auto t_end = std::chrono::high_resolution_clock::now();

double elapsed_time_ms = std::chrono::duration<double, std::milli>(t_end-t_start).count();

2
Без цієї відповіді я б не міг використовувати std :: chrono, дякую!
giles

13

boost 1.46.0 і новіших версій включає бібліотеку Chrono :

Клас thread_clock забезпечує доступ до реального потокового настінного годинника, тобто реального годинника процесора, що викликає потік. Відносний поточний час потоку можна отримати, викликавши thread_clock :: now ()

#include <boost/chrono/thread_clock.hpp>
{
...
    using namespace boost::chrono;
    thread_clock::time_point start = thread_clock::now();
    ...
    thread_clock::time_point stop = thread_clock::now();  
    std::cout << "duration: " << duration_cast<milliseconds>(stop - start).count() << " ms\n";

7
Крім того, C ++ 11 має std::chronoпростір імен з майже однаковим вмістом.
ulidtko

12

У Windows: використовуйте GetTickCount

//GetTickCount defintition
#include <windows.h>
int main()
{

    DWORD dw1 = GetTickCount();

    //Do something 

    DWORD dw2 = GetTickCount();

    cout<<"Time difference is "<<(dw2-dw1)<<" milliSeconds"<<endl;

}

8

Ви також можете використовувати clock_gettime . Цей метод можна використовувати для вимірювання:

  1. Широкосистемний годинник реального часу
  2. Системний монотонний годинник
  3. Час процесора на процес
  4. Час процесора на процес Thread

Код такий:

#include < time.h >
#include <iostream>
int main(){
  timespec ts_beg, ts_end;
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts_beg);
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts_end);
  std::cout << (ts_end.tv_sec - ts_beg.tv_sec) + (ts_end.tv_nsec - ts_beg.tv_nsec) / 1e9 << " sec";
}

`


6

про всяк випадок, коли ви перебуваєте на Unix, ви можете скористатися timeдля отримання часу виконання:

$ g++ myprog.cpp -o myprog
$ time ./myprog

5

Просто примітка: якщо ви працюєте в Windows і вам дійсно потрібна точність, ви можете використовувати QueryPerformanceCounter . Це дає вам час (потенційно) наносекунд .


5

Для мене найпростіший спосіб:

#include <boost/timer.hpp>

boost::timer t;
double duration;

t.restart();
/* DO SOMETHING HERE... */
duration = t.elapsed();

t.restart();
/* DO OTHER STUFF HERE... */
duration = t.elapsed();

використовуючи цей фрагмент коду, вам не потрібно робити класичний end - start.

Насолоджуйтесь улюбленим підходом.


t.elapsed () у сек або мілі-сек?
mkuse

4

Отримати системний час у мілісекундах на початку, і знову в кінці, і відняти.

Щоб отримати кількість мілісекунд з 1970 року в POSIX, ви повинні написати:

struct timeval tv;

gettimeofday(&tv, NULL);
return ((((unsigned long long)tv.tv_sec) * 1000) +
        (((unsigned long long)tv.tv_usec) / 1000));

Щоб отримати кількість мілісекунд з 1601 року в Windows, ви повинні написати:

SYSTEMTIME systime;
FILETIME filetime;

GetSystemTime(&systime);
if (!SystemTimeToFileTime(&systime, &filetime))
    return 0;

unsigned long long ns_since_1601;
ULARGE_INTEGER* ptr = (ULARGE_INTEGER*)&ns_since_1601;

// copy the result into the ULARGE_INTEGER; this is actually
// copying the result into the ns_since_1601 unsigned long long.
ptr->u.LowPart = filetime.dwLowDateTime;
ptr->u.HighPart = filetime.dwHighDateTime;

// Compute the number of milliseconds since 1601; we have to
// divide by 10,000, since the current value is the number of 100ns
// intervals since 1601, not ms.
return (ns_since_1601 / 10000);

Якщо ви дбали про нормалізацію відповіді Windows так, щоб вона також повертала кількість мілісекунд з 1970 року, тоді вам довелося б скорегувати свою відповідь на 11644473600000 мілісекунд. Але це не потрібно, якщо все, що вас турбує, це минулий час.


4

Якщо ви використовуєте:

tstart = clock();

// ...do something...

tend = clock();

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

time = (tend - tstart) / (double) CLOCKS_PER_SEC;

0

Здається, це добре працює для Intel Mac 10.7:

#include <time.h>

time_t start = time(NULL);


    //Do your work


time_t end = time(NULL);
std::cout<<"Execution Time: "<< (double)(end-start)<<" Seconds"<<std::endl;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.