Измерение времени выполнения кода на С++?

Я хочу измерить время выполнения моего кода на С++. Выполнение моего кода занимает около 12 часов, и я хочу написать это время в конце выполнения моего кода. Как я могу сделать это в своем коде?

Операционная система: Linux

Ответы

Ответ 1

Если вы используете С++ 11, вы можете использовать system_clock::now():

auto start = std::chrono::system_clock::now();

/* do some work */

auto end = std::chrono::system_clock::now();
auto elapsed = end - start;
std::cout << elapsed.count() << '\n';

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

// this constructs a duration object using milliseconds
auto elapsed =
    std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

// this constructs a duration object using seconds
auto elapsed =
    std::chrono::duration_cast<std::chrono::seconds>(end - start);

Если вы не можете использовать С++ 11, посмотрите chrono из Boost.

Лучше всего использовать такие стандартные библиотеки, что их переносимость действительно высока (например, они работают в Linux и Windows). Поэтому вам не нужно слишком беспокоиться, если вы решите впоследствии отправить свое приложение.

Эти библиотеки также следуют современным С++-дизайном, в отличие от C-подобных подходов.

EDIT: Приведенный выше пример можно использовать для измерения часов настенных часов. Это, однако, не единственный способ измерить время выполнения программы. Во-первых, мы можем различать пользовательское и системное время:

  • Время пользователя: время, затраченное программой на пространство пользователя.
  • Системное время: время, затраченное программой на системное (или ядро) пространство. Программа входит в пространство ядра, например, при выполнении системного вызова .

В зависимости от целей может потребоваться или не учитывать системное время как часть времени выполнения программы. Например, если цель состоит в том, чтобы просто измерить оптимизацию компилятора на пользовательском коде, то, вероятно, лучше оставить системное время. С другой стороны, если пользователь хочет определить, являются ли системные вызовы значительными накладными расходами, тогда необходимо также измерить системное время.

Кроме того, поскольку большинство современных систем распределены по времени, разные программы могут конкурировать за несколько вычислительных ресурсов (например, CPU). В этом случае можно сделать другое различие:

  • Время настенных часов: используя время настенных часов, выполнение программы измеряется так же, как если бы мы использовали внешние (настенные) часы, Этот подход не учитывает взаимодействие между программами.
  • CPU time: В этом случае мы рассчитываем только время, когда программа фактически работает на CPU. Если программа (P1) совместно запланирована с другой (P2), и мы хотим получить процессорное время для P1, этот подход не включает время, пока P2 работает, а P1 ожидает CPU (в отличие от метод настенных часов).

Для измерения времени процессора Boost включает набор дополнительных часов:

  • process_real_cpu_clock, фиксирует время центрального процессора, затрачиваемое на текущий процесс.
  • process_user_cpu_clock, фиксирует время пользовательского процессора, затраченное текущим процессом.
  • process_system_cpu_clock, фиксирует время системного процессора, затрачиваемое на текущий процесс. Класс, подобный кортежу process_cpu_clock, который захватывает реальные процессы процесса пользователя и процессора и системного процессора вместе.
  • A thread_clock установочные часы потока, дающие время, потраченное текущим потоком (при поддержке платформы).

К сожалению, С++ 11 не имеет таких часов. Но Boost - широко используемая библиотека, и, возможно, эти дополнительные часы будут включены в С++ 1x в какой-то момент. Итак, если вы используете Boost, вы будете готовы, когда новый стандарт С++ добавит их.

Наконец, если вы хотите измерить время, которое программа выполняет для выполнения из командной строки (в отличие от добавления какого-либо кода в вашу программу), вы можете взглянуть на time, как предлагает @BЈови.. Однако этот подход не позволит вам измерять отдельные части вашей программы (например, время, необходимое для выполнения функции).

Ответ 2

Используйте std::chrono::steady_clock, а не std::chrono::system_clock для измерения времени выполнения на С++ 11. Причина в том, что (цитируя system_clock документацию):

в большинстве систем, время в системе может быть отрегулировано в любой момент

в то время как stable_clock является монотонным и лучше подходит для измерения интервалов:

Класс std:: chrono:: stable_clock представляет собой монотонные часы. Время точки этого такта не могут уменьшаться по мере продвижения физического времени. Эти часы не связаны с настенными часами, и лучше всего подходят для интервалы измерения.

Вот пример:

auto start = std::chrono::steady_clock::now();
// do something
auto finish = std::chrono::steady_clock::now();
double elapsed_seconds = std::chrono::duration_cast<
  std::chrono::duration<double> >(finish - start).count();

Небольшой практический совет: если вы измеряете время выполнения и хотите сообщать о секундах std::chrono::duration_cast<std::chrono::seconds>, то редко вам нужно, потому что оно дает вам целых несколько секунд. Чтобы получить время в секундах как double, используйте пример выше.

Ответ 3

Вы можете использовать time, чтобы запустить свою программу. Когда он заканчивается, он печатает красивую статистику времени о запуске программы. Легко настроить, что печатать. По умолчанию он печатает время пользователя и процессор, затраченное на выполнение программы.

РЕДАКТИРОВАТЬ: обратите внимание, что каждая мера из кода неверна, потому что ваше приложение будет заблокировано другими программами, поэтому вы получите неправильные значения *.

* По неправильным значениям я имел в виду, что легко выполнить время, необходимое для выполнения программы, но это время варьируется в зависимости от загрузки ЦП во время выполнения программы. Чтобы получить относительно стабильное измерение времени, которое не зависит от загрузки ЦП, можно выполнить приложение с помощью time и использовать CPU как результат измерения.

Ответ 4

Я использовал что-то вроде этого в одном из моих проектов:

#include <sys/time.h>

struct timeval start, end;
gettimeofday(&start, NULL);
//Compute
gettimeofday(&end, NULL);
double elapsed = ((end.tv_sec - start.tv_sec) * 1000) 
        + (end.tv_usec / 1000 - start.tv_usec / 1000);

Это для миллисекунд, и он работает как для C, так и для С++.

Ответ 5

Если вы хотите напечатать измеренное время с помощью printf(), вы можете использовать это:

auto start = std::chrono::system_clock::now();
/* measured work */
auto end = std::chrono::system_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
printf("Time = %lld ms\n", static_cast<long long int>(elapsed.count()));

Ответ 6

Вы также можете попробовать несколько классов таймера, которые запускаются и останавливаются автоматически, и собирают статистику по среднему, максимальному и минимальному времени, затраченному на любой блок кода, а также количество вызовов. Эти классы cxx-rtimer доступны на GitHub и предлагают поддержку для использования std:: chrono, clock_gettime() или boost:: posix_time в качестве базового источника синхронизации.

С помощью этих таймеров вы можете сделать что-то вроде:

void timeCriticalFunction() {
    static rtimers::cxx11::DefaultTimer timer("expensive");
    auto scopedStartStop = timer.scopedStart();
    // Do something costly...
}

со статистикой времени, записанной в std:: cerr при завершении программы.

Ответ 7

Это код, который я использую:

  const auto start = std::chrono::steady_clock::now();

  // Your code here.

  const auto end = std::chrono::steady_clock::now();
  std::chrono::duration<double> elapsed = end - start;
  std::cout << "Time in seconds: " << elapsed.count() << '\n';

Вы не хотите использовать std::chrono::system_clock потому что это не монотонно! Если пользователь изменит время в середине вашего кода, ваш результат будет неправильным - он может даже быть отрицательным. std::chrono::high_resolution_clock может быть реализован с использованием std::chrono::system_clock поэтому я бы не рекомендовал этого.

Этот код также позволяет избежать уродливых приведений.