Как рассчитать разницу во времени в C ++

96

Как лучше всего рассчитать разницу во времени в C ++? Я измеряю скорость выполнения программы, поэтому меня интересуют миллисекунды. А еще лучше, секунды. Миллисекунды ..

Принятый ответ работает, но должен включать ctime или time.h, как указано в комментариях.

Джек BeNimble
источник
Дупи, но сейчас не могу связать
Роберт Гулд
2
Голосование за закрытие было слишком мало и слишком поздно. Получил рабочий ответ. Тем не менее, хорошая попытка. Кстати, я тоже не нашел ссылку.
Джек BeNimble
Это для окон? затем попробуйте GetTickCount (Windows API)
aJ.
5
Роберт: К счастью, потому что новая публикация позволила еще несколько ответов, один из которых я выбрал. Серьезно, я сомневаюсь в ценности закрытия дублированного сообщения. Что, если бы какие-то решения не были упомянуты в первом? Разработаны новые технологии? Не можете найти из-за разных заголовков?
Джек BeNimble,
2
@JackBeNimble получил несколько "дубликатов", которые не совсем совпадали (возможно, люди, которые, возможно, быстро прочитали вопрос и отметили его, потому что он похож на другой вопрос), я полностью согласен с вашей точкой зрения ... вероятно, точка обмена мета-стеком: o
code_fodder

Ответы:

124

См. 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 () может быть намного хуже. Например, в Windows точность функции clock () составляет примерно 40 мс.
Джон Диблинг,
2
Я пробовал это на Mac 10.7. мое приложение выполняет файл размером 100 МБ за 15 секунд, но время различия составляет 61 секунду. Не много пользы. Я думаю, что time (), вероятно, лучше.
Miek
6
clock()возвращает процессорное время, затраченное программой. Таким образом, если программа запускается параллельно, время, возвращаемое функцией, будет складываться
Амир Джудаки
3
Этот ответ вводит в заблуждение, потому что он показывает время процессора, а не фактическое время настенных часов.
Ультрафиолет
1
Я должен согласиться с Ultraviolet здесь, использование процессорного времени для измерения скорости программы кажется неправильным. OP должен снять отметку с этого ответа как правильный. ИМО, вы должны использовать std :: chrono :: stable_clock :: now (), как описано несколькими ответами в следующем потоке 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;
}
Gongzhitaao
источник
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';
Джереми CD
источник
3
Но boost local_time () не является монотонным, поэтому его не следует использовать для измерения промежутков времени. Я не нашел способа получить доступ к монотонному времени из Boost.
gatopeich
28

Я добавил этот ответ, чтобы уточнить, что принятый ответ показывает время процессора, которое может быть не тем временем, которое вы хотите. Потому что по ссылке есть время процессора и время настенных часов . Время настенных часов - это время, которое показывает фактическое истекшее время независимо от любых других условий, таких как использование ЦП другими процессами. Например, я использовал несколько процессоров , чтобы выполнить определенную задачу и время процессора было высокой 18s , где он на самом деле взял 2s в фактическое время настенных часов.

Чтобы узнать, сколько времени вы делаете,

#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;

}
aJ.
источник
8

Вы также можете использовать clock_gettime . Этот метод можно использовать для измерения:

  1. Общесистемные часы реального времени
  2. Общесистемные монотонные часы
  3. Время ЦП на процесс
  4. Процессорное время на процесс Поток

Код выглядит следующим образом:

#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
Fengshaun
источник
5

Замечание: если вы работаете в Windows и вам действительно нужна точность, вы можете использовать QueryPerformanceCounter . Это дает вам время (потенциально) нано секунд.

v3.
источник
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.

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

user1823890
источник
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;
Miek
источник