Измерение времени работы программы

Мне нужен инструмент для измерения времени работы программы, например gprof. Но разрешение gprof недостаточно хорошее (около 0,01 секунды). oprofile, кажется, может это сделать, я попытаюсь узнать, как получить данные о времени, но не могу.

Итак, кто может рассказать мне, как это сделать, или кто-нибудь знает, что другой инструмент может сделать то же самое?


person martin    schedule 04.02.2010    source источник


Ответы (4)


Измерение времени выполнения всей программы редко бывает полезным при высоком разрешении; слишком много накладных расходов, которые вы обычно не хотите включать при профилировании вещей.

Часто лучше измерять время выполнения только некоторого критического пути, и даже в этом случае часто бывает полезно повторить выполнение этого пути много раз, чтобы повысить точность синхронизации.

В системах Linux/POSIX gettimeofday() часто используется для такой синхронизации, она имеет микросекундную точность:

#include <sys/time.h>
#include <time.h>
#include <stdio.h>

int main(void)
{
  struct timeval then, now;
  int i;

  gettimeofday(&then, NULL);
  for(i = 0; i < 100000; i++)
    my_interesting_function();
  gettimeofday(&now, NULL);

  printf("Did %d executions in %.3g seconds\n", i, now.tv_sec - then.tv_sec + 1e-6 * (now.tv_usec - then.tv_usec));

  return 0;
}

Вышеприведенное предполагает, что my_interesting_function() — это функция, производительность которой вы хотите измерить. Конечно, настройте количество повторений в зависимости от фактического времени выполнения функции.

person unwind    schedule 04.02.2010
comment
@martin: Если вы чувствуете, что это помогло вам, конечно, не стесняйтесь голосовать и/или принимать это. - person unwind; 04.02.2010

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

#include <sys/time.h>
#include <sys/resource.h>

typedef struct tag_time_measure
{
  struct timeval startTimeVal;
  struct timeval stopTimeVal;

  struct rusage startTimeUsage;
  struct rusage stopTimeUsage;
} time_measure;

time_measure * startTimeMeasuring()
{
  time_measure * tu = malloc(sizeof(time_measure));
  if(!tu)
    exit(1);

  getrusage(RUSAGE_SELF, &tu->startTimeUsage);
  gettimeofday(&tu->startTimeVal,0);

  return tu;
}

void stopTimeMeasuring(time_measure * tu)
{
  getrusage(RUSAGE_SELF, &tu->stopTimeUsage);
  gettimeofday(&tu->stopTimeVal,0);
}

void printMeasuredTime(time_measure * tu)
{
  struct timeval elapsedVal;
  struct timeval userVal;
  struct timeval systemVal;

  double elapsed_millis = 0.0f;
  double user_millis = 0.0f;
  double system_millis = 0.0f;

  timersub(&tu->stopTimeVal, &tu->startTimeVal, &elapsedVal);
  timersub(&tu->stopTimeUsage.ru_utime, &tu->startTimeUsage.ru_utime, &userVal);
  timersub(&tu->stopTimeUsage.ru_stime, &tu->startTimeUsage.ru_stime, &systemVal);

  elapsed_millis = elapsedVal.tv_sec * 1000 + (double) elapsedVal.tv_usec / 1000;
  user_millis = userVal.tv_sec * 1000 + (double) userVal.tv_usec / 1000;
  system_millis = systemVal.tv_sec * 1000 + (double) systemVal.tv_usec / 1000;

  printf("\n\n---Program execution times in milliseconds--- \n");
  printf("Total:\t\t %f\nUser:\t\t %f\nSystem:\t\t %f\n", elapsed_millis, user_millis, system_millis);
}

Тогда можно было бы использовать такие функции, как:

int main(void)
{
  time_measure * tu = startTimeMeasuring();

  doSomethingExpensiveHere();

  stopTimeMeasuring(tu);

  printMeasuredTime(tu);

  free(tu);

  return EXIT_SUCCESS;
}

Код можно легко расширить, чтобы воспользоваться другими полезными предложениями rusage (см. http://www.gnu.org/s/libc/manual/html_node/Resource-Usage.html для более подробной информации). Надеюсь, кому-то это будет полезно :)

С уважением, Василий.

person VHristov    schedule 15.06.2010
comment
Не забудьте добавить приведение к (time_measure*) перед этим malloc в функции startTimeMeasuring(), если вы используете C++. - person gbmhunter; 19.07.2013

Если вы работаете в Linux/MacOSX/Unix, вы всегда можете использовать команду time.

Он достаточно точен даже на суперкомпьютере. Время записывается в секундах с точностью до 3 цифр (например, 1,034 с). Единственная проблема заключается в том, что он будет измерять все время выполнения приложения, вы не можете измерять только подпрограммы.

пример использования:

time ./myApplication

В противном случае вам придется написать класс таймера.

person Brock Woolf    schedule 04.02.2010

Если вы просто хотите засечь время, повторите его 10 ^ 3 или 10 ^ 6 раз, как сказано в раскрутке, и понаблюдайте за секундомером. (Я буквально использую свои часы.)

Если вы хотите выяснить, что делает его медленным (совершенно другая проблема), вы можете сделать это лучше, чем gprof. Попробуйте это. Если вам интересно, вот критика gprof.

person Mike Dunlavey    schedule 04.02.2010