Измерение времени, затраченного функцией: clock_gettime - PullRequest
26 голосов
/ 16 октября 2010

Я пытаюсь измерить, сколько времени занимает функция.

У меня есть небольшая проблема: хотя я пытаюсь быть точным и использую плавающие точки, каждый раз, когда я печатаю свой код, используя% 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

Может кто-нибудь сообщить мне, что неверно, или почему я получаю только целые значения, пожалуйста?

Большое спасибо,

Jary

Ответы [ 4 ]

26 голосов
/ 16 октября 2010

Деление целого числа на целое дает целое число.Попробуйте это:

#define BILLION 1E9

И не используйте точку с запятой в конце строки.#define является директивой препроцессора, а не оператором, и в том числе точка с запятой приводит к тому, что BILLION определяется как 1000000000L;, что может прерваться, если вы попытаетесь использовать его в большинстве контекстов.Вам повезло, потому что вы использовали его в самом конце выражения и вне скобок.

9 голосов
/ 16 октября 2010

( requestEnd.tv_nsec - requestStart.tv_nsec ) имеет целочисленный тип и всегда меньше BILLION, поэтому результат деления одного на другой в целочисленной арифметике всегда будет 0.Вам нужно привести результат вычитания к, например, double перед делением.

1 голос
/ 05 августа 2017

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

Пример кода, иллюстрирующий идею:

long accum = ( requestEnd.tv_nsec - requestStart.tv_nsec )
 + ( requestEnd.tv_sec - requestStart.tv_sec ) * BILLION;

Таким образом, вы можете избежать арифметики с плавающей запятой, которая может быть тяжелой для некоторых платформ ...

0 голосов
/ 02 декабря 2016

Обратите внимание, что (requestEnd.tv_nsec - requestStart.tv_nsec) может быть отрицательным, в этом случае вам нужно вычесть 1 секунду из разности tv_sec и добавить один МИЛЛИАРД к разнице tv_nsec.

...