Замерить время работы функции на С++
Мне нужно замерить время выполнения фрагмента кода (можно функции) на С++.
Я прочитал, что для этого используется clock() из модуля time.h (ctime) — она возвращает число таков, измеряемое процессором от начала выполнения программы.
Глобальная константа CLOCKS_PER_SEC хранит число тактов, выполняемое процессором в секунду. Соответственно, чтобы получить время работы программы в секундах достаточно результат работы функции разделить на эту константу:
clock() / CLOCKS_PER_SEC;
Для определения времени работы фрагмента программы нужно определить моменты времени до фрагмента и после него, а затем — посчитать разницу. Однако следующий фрагмент кода работает не так, как мне хотелось бы:
В данном случае я надеюсь получить время, которое пользователь тратит на нажатие клавиши, однако вне зависимости от того, как долго я жду — результат получается примерно одинаковый, а время очень маленьким (см. скриншот). Хотя, если вместо getchar я ставлю фрагмент кода, выполняющий какие-либо вычисления — выводится правдоподобный результат.
Подскажите в чем проблема и как ее решить.

Функция clock() возвращает количество тиков процессора, которое сделала именно ваша программа, т.е. если программа ожидает ввод данных пользователем, то она не работает (операционная система вытесняет процесс из очереди задач). Следовательно нельзя замерить время ожидания ввода при помощи функции clock() — хотя подход, который вы привели, идеально подходит если вы хотите сравнить два алгоритма, т.к. в этом случае меньшее влияние оказывает загруженность системы.
Определить количество секунд, которое выполняется программа можно с помощью функции time() :
Время при этом сохраняет с типом данных time_t — это целое число секунд, прошедшее с 1 января 1970 года. Функция difftime вычисляет разницу двух моментов времени. С помощью такого подхода вы сможете замерить время работы части программы, однако результат будет в секундах.
При помощи средств, появившихся в стандартной библиотеке С++11 можно получить более высокую точность измерения и замерить время независимо от системных часов (с помощью так называемых стабильных часов). Обзор библиотеки chrono.
Следующий фрагмент кода выполняет замер времени с использованием стабильных часов:
Функция std::chrono::duration_cast преобразует объект типа <code>time_point во временной интервал ( duration ), при этом в качестве параметра шаблона передается промежуток времени в виде долей секунды (в данном случае миллисекунды).
Использование библиотеки chrono — лучший способ если нужно фактическое замерить время выполнения программы (в отличии функции time() , модуля time.h она позволяет получить время в миллисекундах и даже наносекундах). Однако если программа работает на многопроцессорной системе и часто ожидает какие-либо данные (не только пользовательский ввод, но и данных от других потоков/процессов) — то больший интерес может представлять реальное время выполнения, возвращаемое функцией clock() модуля time.h . Реальное время лучше отражает потребляемый ресурс процессора, т.к. если текущий процесс простаивает на кластере (где выполняются сотни других приложений), то он вытесняется операционной системой и практически не загружает процессор.
Время выполнения программы C
у меня есть программа на C, которая стремится работать параллельно на нескольких процессорах. Мне нужно иметь возможность записывать время выполнения (которое может быть от 1 секунды до нескольких минут). Я искал ответы, но все они, похоже, предлагают использовать clock() функция, которая затем включает в себя вычисление количества часов, взятых программой, разделенной на Clocks_per_second значение.
Я не уверен, как Clocks_per_second стоимость рассчитывается?
в Java, я просто взял текущее время в миллисекундах до и после выполнения.
есть ли подобная вещь в C? Я посмотрел, но, похоже, не могу найти способ получить что-то лучше, чем второе разрешение.
Я также знаю, что профилировщик будет вариантом, но я хочу реализовать таймер сам.
13 ответов
CLOCKS_PER_SEC — константа, которая объявляется в <time.h> . Чтобы получить время процессора, используемое задачей в приложении C, используйте:
обратите внимание, что это возвращает время в виде с плавающей точкой. Это может быть более точным, чем второй (например, вы измеряете 4.52 секунды). Точность зависит от архитектуры; на современных системах вы легко получаете 10 мс или ниже, но на старых машинах Windows (с эпохи Win98) это было ближе к 60 мс.
clock() стандартный C; он работает «везде.» Существуют системные функции, такие как getrusage() в Unix-подобных системах.
в Java System.currentTimeMillis() не измеряет то же самое. Это «настенные часы»: он может помочь вам измерить, сколько времени потребовалось для выполнения программы, но он не говорит вам, сколько времени процессора было использовано. В многозадачных системах (т. е. во всех) они могут быть совершенно разными.
Если вы используете оболочку Unix для запуска, вы можете использовать команду time.
предполагая a.out как исполняемый файл даст u время, необходимое для запуска этого
вы функционально хотите этого:
обратите внимание, что измеряется в микросекундах, а не только секунд.
в простой ванили C:
большинство простых программ имеют время вычисления в миллисекундах. Так что, я полагаю, вы найдете это полезным.
Если вы хотите вычислить время выполнения всей программы, и вы находитесь в системе Unix, запустите программу с помощью времени такой time ./a.out
многие ответы предлагали clock() а то CLOCKS_PER_SEC С time.h . Это, вероятно, плохая идея, потому что это то, что моя говорит:
так CLOCKS_PER_SEC может быть определено как 1000000, в зависимости от того, какие параметры вы используете для компиляции, и поэтому это не кажется хорошим решением.
вы должны учитывать, что измерения времени это заняло программу для выполнения, во многом зависит от нагрузки, которую машина имеет в этот конкретный момент.
зная, что способ получения текущего времени в C может быть достигнут разными способами, Проще:
надеюсь, что это помогает.
ANSI C указывает только функции времени второй точности. Однако, если вы работаете в среде POSIX вы можете использовать gettimeofday() функция, которая обеспечивает разрешение микросекунд времени, прошедшего с эпохи UNIX.
в качестве примечания я бы не рекомендовал использовать clock (), так как он плохо реализован на многих(если не на всех?) системы и не точны, кроме того, что это относится только к тому, как долго ваша программа потратила на процессор, а не всего срок службы программы, который, согласно вашему вопросу, я предполагаю, что вы хотели бы измерить.
Stopwatch Класс
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Предоставляет набор методов и свойств, которые можно использовать для точного измерения затраченного времени.
Примеры
В следующем примере показано, как использовать Stopwatch класс для определения времени выполнения приложения.
В следующем примере показано использование Stopwatch класса для вычисления данных о производительности.
Комментарии
Stopwatch Экземпляр может измерять затраченное время на один интервал или общее время, прошедшее через несколько интервалов. В типичном Stopwatch сценарии вы вызываете Start метод, а затем в конечном итоге вызываете Stop метод, а затем проверяете прошедшее время с помощью Elapsed свойства.
Stopwatch Экземпляр выполняется или останавливается; используется для IsRunning определения текущего состояния объектаStopwatch. Используется Start для начала измерения затраченного времени; используется Stop для остановки измерения затраченного времени. Запрос значения затраченного времени с помощью свойств ElapsedElapsedMillisecondsили ElapsedTicks. Вы можете запросить затраченные свойства времени во время выполнения или остановки экземпляра. Свойства затраченного времени постоянно увеличиваются во время Stopwatch выполнения; они остаются постоянными при остановке экземпляра.
По умолчанию затраченное значение времени экземпляра Stopwatch равно общему значению всех измеренных интервалов времени. Каждый вызов Start начинает подсчет в совокупное затраченное время; каждый вызов заканчивает Stop текущее измерение интервала и зависает совокупное значение затраченного времени. Reset Используйте метод для очистки совокупного затраченного времени в существующем Stopwatch экземпляре.
Меры Stopwatch , прошедшие время путем подсчета тактов таймера в базовом механизме таймера. Если установленное оборудование и операционная система поддерживают счетчик производительности с высоким разрешением, Stopwatch класс использует этот счетчик для измерения затраченного времени. В Stopwatch противном случае класс использует системный таймер для измерения затраченного времени. Frequency Используйте поля для IsHighResolution определения точности и разрешения Stopwatch реализации времени.
Класс Stopwatch помогает управлять счетчиками производительности, связанными с временем, в управляемом коде. В частности, Frequency поле и GetTimestamp метод можно использовать вместо неуправляемых Windows API QueryPerformanceFrequency и QueryPerformanceCounter .
На компьютере с несколькими обработчиками не имеет значения, на каком процессоре выполняется поток. Однако из-за ошибок в BIOS или аппаратном уровне абстракции (HAL) можно получить разные результаты времени на разных процессорах. Чтобы указать сходство процессора для потока, используйте ProcessThread.ProcessorAffinity метод.
Конструкторы
Инициализирует новый экземпляр класса Stopwatch.
Получает частоту таймера в виде количества тактов в секунду. Это поле доступно только для чтения.
Указывает, зависит ли таймер от счетчика производительности высокого разрешения. Это поле доступно только для чтения.
Свойства
Получает общее затраченное время, измеренное текущим экземпляром.
Получает общее затраченное время в миллисекундах, измеренное текущим экземпляром.
Получает общее затраченное время в тактах таймера, измеренное текущим экземпляром.
Получает значение, указывающее, запущен ли таймер Stopwatch.
Методы
Определяет, равен ли указанный объект текущему объекту.
Возвращает затраченное время с момента startingTimestamp получения значения с помощью GetTimestamp().
Возвращает затраченное время между двумя метками времени, извлеченными с помощью GetTimestamp().
Служит хэш-функцией по умолчанию.
Получает текущее число тактов временного механизма.
Возвращает объект Type для текущего экземпляра.
Создает неполную копию текущего объекта Object.
Останавливает измерение интервала времени и обнуляет затраченное время.
Останавливает измерение интервала времени, обнуляет затраченное время и начинает измерение затраченного времени.
Запускает или возобновляет измерение затраченного времени для интервала.
Инициализирует новый экземпляр Stopwatch, задает свойство затраченного времени равным нулю и запускает измерение затраченного времени.