Как я могу получить время выполнения программы в миллисекундах в 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. Эй, это ПК, что ты ожидал???