Легко измерить прошедшее время - PullRequest
258 голосов
/ 11 мая 2010

Я пытаюсь использовать time () для измерения различных точек моей программы.

Что я не понимаю, так это то, почему значения до и после одинаковы?Я понимаю, что это не лучший способ для профилирования моей программы, я просто хочу посмотреть, как долго что-то займет.

printf("**MyProgram::before time= %ld\n", time(NULL));

doSomthing();
doSomthingLong();

printf("**MyProgram::after time= %ld\n", time(NULL));

Я пытался:

struct timeval diff, startTV, endTV;

gettimeofday(&startTV, NULL); 

doSomething();
doSomethingLong();

gettimeofday(&endTV, NULL); 

timersub(&endTV, &startTV, &diff);

printf("**time taken = %ld %ld\n", diff.tv_sec, diff.tv_usec);

Как мне прочитать результат **time taken = 0 26339?Означает ли это, что 26339 наносекунд = 26,3 мсек?

Как насчет **time taken = 4 45025, это значит 4 секунды и 25 мсек?

Ответы [ 23 ]

1 голос
/ 20 марта 2019

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

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

template <typename clock_t = std::chrono::steady_clock>
struct scoped_timer {
  using duration_t = typename clock_t::duration;
  const std::function<void(const duration_t&)> callback;
  const std::chrono::time_point<clock_t> start;

  scoped_timer(const std::function<void(const duration_t&)>& finished_callback) :
      callback(finished_callback), start(clock_t::now()) { }
  scoped_timer(std::function<void(const duration_t&)>&& finished_callback) :
      callback(finished_callback), start(clock_t::now()) { }
  ~scoped_timer() { callback(clock_t::now() - start); }
};

Структура перезвонит вам в предоставленном функторе, когда он выйдет из области видимости, чтобы вы могли что-то сделать с информацией о времени (распечатать или сохранить ее или что-то еще). Если вам нужно сделать что-то еще более сложное, вы можете использовать std::bind с std::placeholders для вызова функций с большим количеством аргументов.

Вот краткий пример его использования:

void test(bool should_throw) {
  scoped_timer<> t([](const scoped_timer<>::duration_t& elapsed) {
    auto e = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(elapsed).count();
    std::cout << "took " << e << "ms" << std::endl;
  });

  std::this_thread::sleep_for(std::chrono::seconds(1));

  if (should_throw)
    throw nullptr;

  std::this_thread::sleep_for(std::chrono::seconds(1));
}

Если вы хотите быть более преднамеренным, вы также можете использовать new и delete, чтобы явно запускать и останавливать таймер, не полагаясь на то, что вы можете это сделать.

0 голосов
/ 26 января 2015

В ответ на три конкретных вопроса ОП

«Чего я не понимаю, так это того, почему значения до и после одинаковы? »

Первый вопрос и пример кода показывают, что time() имеет разрешение 1 секунда, поэтому ответ должен состоять в том, что две функции выполняются менее чем за 1 секунду. Но иногда (по-видимому, нелогично) сообщит 1 секунду , если две метки таймера пересекают границу в одну секунду.

В следующем примере используется gettimeofday(), который заполняет эту структуру

struct timeval {
    time_t      tv_sec;     /* seconds */
    suseconds_t tv_usec;    /* microseconds */
};

и второй вопрос спрашивает: «Как мне прочитать результат **time taken = 0 26339? Означает ли это 26 339 наносекунд = 26,3 мс?»

Мой второй ответ: время составляет 0 секунд и 26339 микросекунд, то есть 0,026339 секунд, что подтверждает первый пример, выполненный менее чем за 1 секунду.

В третий вопрос спрашивает: «А как же **time taken = 4 45025, это значит 4 секунды и 25 мс?»

Мой третий ответ - это время, которое занимает 4 секунды и 45025 микросекунд, то есть 4,045025 секунды, что показывает, что OP изменил задачи, выполняемые двумя функциями, которые он ранее рассчитывал.

0 голосов
/ 23 сентября 2015

Вы можете использовать SFML-библиотеку , которая является простой и быстрой мультимедийной библиотекой. Он включает в себя множество полезных и четко определенных классов, таких как Clock, Socket, Sound, Graphics и т. Д. Это так просто в использовании и настоятельно рекомендуется.

Это пример для этого вопроса.

sf::Clock clock;
...
Time time1 = clock.getElapsedTime();
...
Time time2 = clock.restart();
...