Время измерения по функции: clock_gettime
Я пытаюсь измерить, сколько времени занимает функция.
У меня есть небольшая проблема: хотя я стараюсь быть точным и использую плавающие точки, каждый раз, когда я печатаю свой код, используя% lf, я получаю один из двух ответов: 1.000... или 0.000.... Это приводит меня интересует, правильный ли мой код:
#define BILLION 1000000000L;
// Calculate time taken by a request
struct timespec requestStart, requestEnd;
clock_gettime(CLOCK_REALTIME, &requestStart);
function_call();
clock_gettime(CLOCK_REALTIME, &requestEnd);
// Calculate time it took
double accum = ( requestEnd.tv_sec - requestStart.tv_sec )
+ ( requestEnd.tv_nsec - requestStart.tv_nsec )
/ BILLION;
printf( "%lf\n", accum );
Большая часть этого кода не была сделана мной. На этой странице примера был код, иллюстрирующий использование clock_gettime: http://www.users.pjwstk.edu.pl/~jms/qnx/help/watcom/clibref/qnx/clock_gettime.html
Может кто-нибудь, пожалуйста, сообщите мне, что является неправильным, или почему я получаю только целые значения?
Большое спасибо,
Джари
Ответы
Ответ 1
Разделение целого на целое число дает целое число. Попробуйте следующее:
#define BILLION 1E9
И не используйте точку с запятой в конце строки. #define
- это препроцессорная директива, а не оператор, и в том числе точка с запятой, в результате которой BILLION определяется как 1000000000L;
, который сломается, если вы попытаетесь использовать его в большинстве контекстов. Вам повезло, потому что вы использовали его в самом конце выражения и вне любых круглых скобок.
Ответ 2
( requestEnd.tv_nsec - requestStart.tv_nsec )
имеет целочисленный тип и всегда меньше BILLION
, поэтому результат деления одного на другой в целочисленной арифметике всегда будет 0
. Вы должны выдать результат вычитания, например. double
перед делением.
Ответ 3
Обратите внимание, что (requestEnd.tv_nsec - requestStart.tv_nsec) может быть отрицательным, и в этом случае вам нужно вычесть 1 секунду из разницы tv_sec и добавить один BILLION в разницу tv_nsec.
Ответ 4
Я знаю, что вопрос был опубликован давно, но я до сих пор не вижу ответа, который бы предложил вам "преобразовать" прошедшее время в наносекунды (или миллисекунды), а не в секундах, как в вашем примере кода.
Пример фрагмента кода для иллюстрации идеи:
long accum = ( requestEnd.tv_nsec - requestStart.tv_nsec )
+ ( requestEnd.tv_sec - requestStart.tv_sec ) * BILLION;
Таким образом, вы можете избежать арифметики с плавающей запятой, которая может быть тяжелой для некоторых платформ...