Как я могу получить время выполнения программы в миллисекундах в C?

В настоящее время я получаю время выполнения моей программы в секундах, вызывая:

time_t startTime = time(NULL);
//section of code
time_t endTime = time(NULL);
double duration = difftime(endTime, startTime);

Можно ли получить время стены в миллисекундах? Если так, как?

6 ответов

Решение

Если вы работаете на POSIX-машине, используйте gettimeofday() вместо; это дает вам разумную мобильность и микросекундное разрешение.

Чуть более эзотерическим, но и в POSIX, является clock_gettime() функция, которая дает вам наносекундное разрешение.

Во многих системах вы найдете функцию ftime() это на самом деле возвращает вам время в секундах и миллисекундах. Однако его больше нет в спецификации Single Unix (примерно так же, как в POSIX). Вам нужен заголовок <sys/timeb.h>:

struct timeb mt;
if (ftime(&mt) == 0)
{
     mt.time ... seconds
     mt.millitime ... milliseconds
}

Это относится, по крайней мере, к версии 7 (или 7-й редакции) Unix, поэтому она была очень широко доступна.

У меня также есть примечания в моем таймере под-секунды на times() а также clock(), которые используют другие структуры и заголовки снова. У меня также есть заметки об использовании Windows clock() с 1000 тактов в секунду (миллисекундная синхронизация) и более старым интерфейсом GetTickCount() который отмечен как необходимый на Windows 95, но не на NT.

Если вы можете сделать это вне самой программы, в Linux вы можете использовать time команда (time ./my_program).

Недавно я написал пост в блоге, который объясняет, как получить время в кроссплатформенных миллисекундах.

Он будет работать как время (NULL), но будет возвращать количество миллисекунд вместо секунд из эпохи Unix как в Windows, так и в Linux.

Вот код

#ifdef WIN32
#include <Windows.h>
#else
#include <sys/time.h>
#include <ctime>
#endif

/* Returns the amount of milliseconds elapsed since the UNIX epoch. Works on both
 * windows and linux. */

int64 GetTimeMs64()
{
#ifdef WIN32
 /* Windows */
 FILETIME ft;
 LARGE_INTEGER li;
 uint64 ret;

 /* Get the amount of 100 nano seconds intervals elapsed since January 1, 1601 (UTC) and copy it
  * to a LARGE_INTEGER structure. */
 GetSystemTimeAsFileTime(&ft);
 li.LowPart = ft.dwLowDateTime;
 li.HighPart = ft.dwHighDateTime;

 ret = li.QuadPart;
 ret -= 116444736000000000LL; /* Convert from file time to UNIX epoch time. */
 ret /= 10000; /* From 100 nano seconds (10^-7) to 1 millisecond (10^-3) intervals */

 return ret;
#else
 /* Linux */
 struct timeval tv;
 uint64 ret;

 gettimeofday(&tv, NULL);

 ret = tv.tv_usec;
 /* Convert from micro seconds (10^-6) to milliseconds (10^-3) */
 ret /= 1000;

 /* Adds the seconds (10^0) after converting them to milliseconds (10^-3) */
 ret += (tv.tv_sec * 1000);

 return ret;
#endif
}

Вы можете изменить его так, чтобы он возвращал микросекунды вместо миллисекунд, если хотите.

Библиотека GLib с открытым исходным кодом имеет систему GTimer, которая утверждает, что обеспечивает микросекундную точность. Эта библиотека доступна в Mac OS X, Windows и Linux. В настоящее время я использую его для измерения производительности в Linux, и, похоже, он отлично работает.

gprof, которая является частью инструментария GNU, является опцией. На большинстве систем POSIX он установлен, и он доступен в Cygwin для Windows. Отслеживание времени самостоятельно gettimeofday() работает нормально, но это эквивалент производительности использования операторов print для отладки. Хорошо, если вы просто хотите быстрое и грязное решение, но оно не так элегантно, как использование подходящих инструментов.

Использовать gprof, вы должны указать опцию -pg при компиляции с gcc как в:

gcc -o prg source.c -pg

Тогда вы можете запустить gprof по сгенерированной программе следующим образом:

gprof prg > gprof.out

По умолчанию gprof генерирует общее время выполнения вашей программы, а также количество времени, затрачиваемого на каждую функцию, количество раз, которое вызывалась каждая функция, среднее время, затраченное на каждый вызов функции, и аналогичную информацию.

Есть большое количество опций, которые вы можете установить с помощью gprof, Если вы заинтересованы, есть больше информации на страницах руководства или через Google.

В Windows используйте QueryPerformanceCounter и связанный с ним QueryPerformanceFrequency. Они не дают вам время, которое можно перевести на календарное время, поэтому, если вам это нужно, спросите время, используя CRT API, а затем немедленно используйте QueryPerformanceCounter. Затем вы можете сделать некоторое простое сложение / вычитание для вычисления календарного времени с некоторой ошибкой из-за времени, которое требуется для последовательного выполнения API. Эй, это ПК, что ты ожидал???

Другие вопросы по тегам