Я пытаюсь использовать время () для измерения различных точек моей программы.
Что я не понимаю, так это то, почему значения в до и после одинаковы? Я понимаю, что это не лучший способ для профилирования моей программы, я просто хочу посмотреть, как долго что-то займет.
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
? Означает ли это, что 26,339 наносекунд = 26,3 мсек?
А что **time taken = 4 45025
, это означает 4 секунды и 25 мс?
time()
возвращает другое значение.time(NULL)
... во второй раз, когда вы звоните, оно будет через N секунд после первого и, следовательно, ... другим (если вы не делаете не займет и секунды, чтобы завершить ... в этом случае это будет так же, как первый).Ответы:
источник
#include <chrono>
директиву и я хотел бы изменить время представления отчетности , как:std::cout << "Time difference (sec) = " << (std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()) /1000000.0 <<std::endl;
(и не забыть C ++ 11 флага при компиляции:-std=c++11
)time()
Функция является точной только в течение одной секунды, но естьCLOCKS_PER_SEC
«часы» в течение одной секунды. Это простое, портативное измерение, даже если оно чрезмерно упрощено.источник
clock()
измеряет процессорное время, а не фактическое истекшее время (которое может быть намного больше).Вы можете абстрагировать механизм измерения времени и измерять время выполнения каждого вызываемого объекта с минимальным дополнительным кодом , просто вызывая его через структуру таймера. Кроме того, во время компиляции вы можете параметризовать тип синхронизации (миллисекунды, наносекунды и т. Д.).
Благодаря обзору Loki Astari и предложению использовать вариадические шаблоны. Вот почему перенаправленный вызов функции.
Demo
Согласно комментарию Говарда Хиннанта , лучше не выходить из системы хронографа, пока мы не должны. Таким образом, вышеприведенный класс может дать пользователю возможность
count
вручную вызывать , предоставляя дополнительный статический метод (показано в C ++ 14).и быть наиболее полезным для клиентов, которые
Полный код можно найти здесь . Моя попытка создать инструмент для тестирования производительности на основе хронографа описана здесь .
Если
std::invoke
доступны C ++ 17 , вызов вызываемого объектаexecution
может быть выполнен следующим образом:обеспечить вызываемые элементы, которые являются указателями на функции-члены.
источник
code_timer
), который принимает время начала (std::chrono::system_clock::now();
) в конструкторе, метод,code_timer::ellapsed
который измеряет разницу между новымnow()
вызовом и тем, что в конструкторе иcode_timer::reset
метод, который сбрасывает время начала до новогоnow()
результата. Чтобы измерить выполнение функтора в моем коде, я использую свободную функцию вне класса. Это позволяет измерять время от построения объекта до завершения асинхронного вызова.chrono
системы, пока вам не придется (избегайте использования.count()
). Пусть клиент звонит,.count()
когда вынужден (скажем, для ввода / вывода, что действительно неудачно). Клиент может захотеть постобработать несколько периодов до ввода / вывода (например, в среднем), и это лучше всего сделать вchrono
системе.std::forward<F>(func)
?std::forward<decltype(func)>(func)
потому что он может применяться к аргументам универсального lambdas (auto&& func
), гдеF
нет синтаксического там, и его легко абстрагировать в служебном макросе,#define fw(arg) std::forward<decltype(arg)>(arg)
который я делаю в моей библиотеке тестов (так что это синтаксический остаток, над которым я не особо разбираюсь) ответ)Как я вижу из вашего вопроса, похоже, что вы хотите знать, сколько времени прошло после выполнения некоторого фрагмента кода. Я полагаю, вам будет удобно увидеть результаты в секундах. Если это так, попробуйте использовать
difftime()
функцию, как показано ниже. Надеюсь, это решит вашу проблему.источник
Только для Windows: (тег Linux был добавлен после того, как я опубликовал этот ответ)
Вы можете использовать GetTickCount (), чтобы получить количество миллисекунд, прошедших с момента запуска системы.
источник
SleepEx(5000,0)
вместо // Выполнение трудоемкой операции и разностьafter
иbefore
составила почти 5 секунд.time(NULL)
возвращает количество секунд, прошедших с 01.01.1970 в 00:00 ( эпоха ). Таким образом, разница между двумя значениями - это количество секунд, затраченное на обработку.Вы можете получить более точные результаты
getttimeofday()
, которые возвращают текущее время в секундах, какtime()
и в микросекундах.источник
функция времени (NULL) возвращает количество секунд, прошедших с 01.01.1970 в 00:00. И поскольку эта функция вызывается в разное время в вашей программе, она всегда будет разной. Время в C ++
источник
Использование ниже ::
Это похоже на RAII по объему
ПРИМЕЧАНИЕ это не мое, но я подумал, что это уместно здесь
источник
источник
Значения, напечатанные вашей второй программой, представляют собой секунды и микросекунды.
источник
источник
C ++ std :: chrono имеет явное преимущество кроссплатформенности. Тем не менее, он также вносит значительные накладные расходы по сравнению с POSIX clock_gettime (). На моем Linux-компьютере все
std::chrono::xxx_clock::now()
разновидности работают примерно одинаково:Хотя POSIX
clock_gettime(CLOCK_MONOTONIC, &time)
должен быть таким же, какsteady_clock::now()
но он более чем в 3 раза быстрее!Вот мой тест, для полноты.
И это вывод, который я получаю при компиляции с gcc7.2 -O3:
источник
time(NULL)
Вызов функции возвращает количество секунд , прошедшее с момента EPOC: 1 января 1970 года Возможно , что вы имеете в виду , чтобы сделать , это взять разницу между двумя отметками:источник
Как уже отмечали другие, функция time () в стандартной библиотеке C не имеет разрешения лучше одной секунды. Похоже, единственной полностью переносимой функцией C, которая может обеспечить лучшее разрешение, является clock (), но она измеряет время процессора, а не время настенных часов. Если кто-то ограничен платформой POSIX (например, Linux), то функция clock_gettime () - хороший выбор.
Начиная с C ++ 11 доступны гораздо лучшие средства синхронизации, которые предлагают лучшее разрешение в форме, которая должна быть очень переносимой для разных компиляторов и операционных систем. Точно так же библиотека boost :: datetime предоставляет хорошие классы синхронизации высокого разрешения, которые должны быть легко переносимыми.
Одной из проблем при использовании любого из этих средств является задержка, вызванная запросом системных часов. Из экспериментов с clock_gettime (), boost :: datetime и std :: chrono, эта задержка может легко составлять несколько микросекунд. Таким образом, при измерении длительности любой части вашего кода вы должны учитывать наличие ошибки измерения примерно такого размера или пытаться каким-то образом исправить эту нулевую ошибку. В идеале вам может потребоваться собрать несколько измерений времени, затраченного вашей функцией, и вычислить среднее или максимальное / минимальное время, затраченное на несколько прогонов.
Чтобы помочь решить все эти проблемы переносимости и сбора статистики, я разработал библиотеку cxx-rtimers, доступную на Github, которая пытается предоставить простой API для блоков синхронизации кода C ++, вычисления нулевых ошибок и отчетности по статистике из встроенных таймеров. в вашем коде. Если у вас есть компилятор C ++ 11, вы просто
#include <rtimers/cxx11.hpp>
используете что-то вроде:При выходе из программы вы получите сводную статистику по времени, записанную в std :: cerr, такую как:
который показывает среднее время, его стандартное отклонение, верхний и нижний пределы и количество раз, когда эта функция была вызвана.
Если вы хотите использовать специфичные для Linux функции синхронизации, вы можете
#include <rtimers/posix.hpp>
или, если у вас есть библиотеки Boost, но более старый компилятор C ++, вы можете это сделать#include <rtimers/boost.hpp>
. Существуют также версии этих классов таймеров, которые могут собирать статистическую информацию о времени из разных потоков. Существуют также методы, позволяющие оценить нулевую ошибку, связанную с двумя непосредственно последовательными запросами системных часов.источник
Внутренне функция будет обращаться к системным часам, поэтому каждый раз, когда вы их вызываете, она возвращает разные значения. В целом, в нефункциональных языках может быть много побочных эффектов и скрытого состояния в функциях, которые вы не можете увидеть, просто взглянув на имя и аргументы функции.
источник
Из того, что видно, tv_sec хранит прошедшие секунды, в то время как tv_usec хранит прошедшие отдельно микросекунды. И они не являются обращением друг друга. Следовательно, они должны быть изменены на соответствующую единицу и добавлены, чтобы получить общее время, прошедшее.
источник
В linux clock_gettime () - один из лучших вариантов. Вы должны связать библиотеку в реальном времени (-lrt).
источник
Мне нужно было измерить время выполнения отдельных функций в библиотеке. Я не хотел оборачивать каждый вызов каждой функции функцией измерения времени, потому что это уродливо и углубляет стек вызовов. Я также не хотел помещать код таймера вверху и внизу каждой функции, потому что он создает беспорядок, когда функция может рано выйти или выдать исключения, например. В итоге я сделал таймер, который использует свое время жизни для измерения времени.
Таким образом, я могу измерить время простоя блока кода, просто создав экземпляр одного из этих объектов в начале рассматриваемого блока кода (в действительности функции или любой области видимости), а затем позволяя деструктору экземпляров измерять время, прошедшее с момента строительство, когда экземпляр выходит за рамки. Вы можете найти полный пример здесь, но структура очень проста:
Структура перезвонит вам по предоставленному функтору, когда он выйдет из области видимости, чтобы вы могли что-то сделать с информацией о времени (распечатать или сохранить ее или что-то еще). Если вам нужно сделать что - то еще более сложными вы можете использовать даже
std::bind
сstd::placeholders
обратным вызовом функции с большим количеством аргументов.Вот быстрый пример его использования:
Если вы хотите быть более взвешенным, вы также можете использовать
new
иdelete
явно запускать и останавливать таймер, не полагаясь на то, что он сделает это за вас.источник
Они одинаковы, потому что ваша функция doSomething происходит быстрее, чем гранулярность таймера. Пытаться:
источник
Причина, по которой оба значения одинаковы, заключается в том, что ваша длинная процедура не занимает столько времени - менее одной секунды. Вы можете попробовать просто добавить длинный цикл (for (int i = 0; i <100000000; i ++);) в конце функции, чтобы убедиться, что это проблема, тогда мы можем перейти оттуда ...
В случае, если вышеприведенное окажется верным, вам потребуется найти другую системную функцию (я понимаю, вы работаете над linux, поэтому я не могу помочь вам с именем функции) для более точного измерения времени. Я уверен, что есть функция, похожая на GetTickCount () в Linux, вам просто нужно найти ее.
источник
Я обычно использую следующее:
Это то же самое, что предложил @ nikos-athanasiou, за исключением того, что я избегаю использования нестационарных часов и использую плавающее число секунд в качестве продолжительности.
источник
high_resolution_clock
это typedef для либоsystem_clock
илиsteady_clock
. Таким образом, чтобы проследить, чтоstd::conditional
еслиis_steady
часть истинна, тогда вы выбираете,high_resolution_clock
который является (typedef)steady_clock
. Если это неверно, вы выбираетеsteady_clock
снова. Просто используйтеsteady_clock
с самого начала ...high_resolution_clock may be a synonym for system_clock or steady_clock
. Причина заключается в следующем:high_resolution_clock
представляет часы с самым коротким периодом тиков, поэтому, независимо от реализации, у нее есть два варианта: постоянный или нет. Какой бы выбор мы ни сделали, сказать, что реализация будет отличаться от двух других тактовых импульсов, все равно, что сказать, что у нас есть лучшая реализация для устойчивых (или нет) тактовых импульсов, которые мы решили не использовать (для устойчивых или нет тактовых генераторов). Знать, как хорошо, знать, почему лучшеВ ответ на три конкретных вопроса ОП .
«Что я не понимаю, так это то, почему значения до и после одинаковы? »
Первый вопрос и образец кода показывает , что
time()
имеет разрешение в 1 секунду, так что ответ должен быть , что эти две функции выполняют менее чем за 1 секунду. Но иногда это (очевидно, нелогично) сообщит 1 секунду если две метки таймера пересекают границу в одну секунду.Следующий пример использует
gettimeofday()
который заполняет эту структуруи второй вопрос спрашивает: «Как я могу прочитать результат
**time taken = 0 26339
? Означает ли это 26 339 наносекунд = 26,3 мс?»Мой второй ответ: время составляет 0 секунд и 26339 микросекунд, то есть 0,026339 секунд, что подтверждает первый пример, выполненный менее чем за 1 секунду.
Третий вопрос спрашивает: « А что
**time taken = 4 45025
, это означает 4 секунды и 25 мс?»Мой третий ответ - это 4 секунды и 45025 микросекунд, то есть 4,045025 секунд, что показывает, что OP изменил задачи, выполняемые двумя функциями, которые он ранее рассчитывал.
источник
Пример, подобный приведенному здесь, только с дополнительной функцией преобразования + распечатка.
источник
Я создал класс для автоматического измерения прошедшего времени. Пожалуйста, проверьте код (c ++ 11) по этой ссылке: https://github.com/sonnt174/Common/blob/master/time_measure.h
Пример использования класса TimeMeasure:
источник
Matlab
ароматный!tic
запускает секундомер для измерения производительности. Функция записывает внутреннее время при выполнении команды tic. Отображение прошедшего времени с помощьюtoc
функции.источник
Вы можете использовать библиотеку SFML , которая является простой и быстрой мультимедийной библиотекой. Он включает в себя множество полезных и четко определенных классов, таких как Clock, Socket, Sound, Graphics и т. Д. Он очень прост в использовании и настоятельно рекомендуется.
Это пример для этого вопроса.
источник