Как получить время выполнения программы в миллисекундах на языке Си?
В настоящее время я получаю время выполнения моей программы в секундах, вызывая:
time_t startTime = time(NULL);
//section of code
time_t endTime = time(NULL);
double duration = difftime(endTime, startTime);
Можно ли получить время стены в миллисекундах ? Если да, то как?
6 ответов:
Если вы находитесь на машине POSIX-ish, используйте
gettimeofday()вместо этого; это дает вам разумную переносимость и разрешение микросекунды.Несколько более эзотерическим, но также и в POSIX, является
Во многих системах вы найдете функциюclock_gettime()функция, которая дает вам разрешение наносекунды.ftime(), которая фактически возвращает вам время в секундах и миллисекундах. Однако он больше не входит в единую спецификацию 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).
Недавно я написал пост в блоге, который объясняет, Как получить время в миллисекундах кросс-платформенным .
Он будет работать как time (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. Если вам интересно, вы можете найти дополнительную информацию на man-страницах или в Google.
В Windows используйте QueryPerformanceCounter и связанную с ним QueryPerformanceFrequency. Они не дают вам время, которое можно перевести в календарное время, поэтому, если вам это нужно, попросите время с помощью CRT API, а затем немедленно используйте QueryPerformanceCounter. Затем вы можете выполнить простое сложение / вычитание для вычисления календарного времени с некоторой ошибкой из-за времени, необходимого для последовательного выполнения API. Эй, это же компьютер, а ты чего ожидал???
Comments