2010-10-15 3 views
24

Я пытаюсь измерить, сколько времени займет функция.Время измерения, выполняемое функцией: 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

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

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

Jary

+11

Нет, нет, нет: Дон» t присваивать имена цифрам. Вместо этого используйте функцию, которую они обслуживают: '#define CLOCK_PRECISION 1000000000L/* один миллиард * /' – pmg

+9

@pmg: тангенс педантизма: я бы сказал, что имя, такое как 'CLOCK_PRECISION', было бы необходимо, только если единицы не были ясны из имя переменной. В приведенном выше примере из названия «tv_nsec» ясно, что мы находимся в наносекундах. Поэтому 'NANOSECONDS_PER_SECOND' может быть уместным, но это действительно не так уж и отличается от простоты' BILLION'. –

ответ

22

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

#define BILLION 1E9 

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

+2

Большое спасибо за вашу помощь. И спасибо, что позволили мне узнать о запятой, это то, что я забыл. Большое спасибо! – Jary

+0

Для производительности .. #define ONE_OVER_BILLION 1E-9 и использовать умножить. – linleno

9

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

1

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

0

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

фрагмент пример кода для иллюстрации идеи:

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

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