Измерение прошедшего времени в python - программирование
Подтвердить что ты не робот

Измерение прошедшего времени в python

Существует ли простой способ/модуль правильно измерить прошедшее время в python? Я знаю, что я могу просто называть time.time() дважды и учитывать разницу, но это приведет к неправильным результатам, если системное время будет изменено. Конечно, это происходит не очень часто, но это указывает на то, что я измеряю неправильную вещь.

Использование time.time() для измерения продолжительности невероятно круговое, когда вы думаете об этом. Вы принимаете разницу между двумя измерениями абсолютного времени, которые, в свою очередь, построены по измерениям продолжительности (выполняются таймерами) и известным абсолютным временам (устанавливаются вручную или через ntp), что вас совсем не интересует.

Итак, есть ли способ запросить это "время таймера" напрямую? Я бы предположил, что его можно представить как миллисекунду или микросекунду, которая не имеет значимого абсолютного представления (и, следовательно, ее не нужно настраивать с системным временем). Оглядываясь немного, кажется, что это именно то, что System.nanoTime() делает в Java, но я не нашел соответствующую функцию Python, хотя он должен (технически-технически) быть проще, чем time.time().

Изменить: Чтобы избежать путаницы и ответить на приведенные ниже ответы: речь идет не о изменениях DST, и я также не хочу процессорного времени - я хочу истекшее физическое время. Он не должен быть очень мелкозернистым и даже не особенно точным. Это просто не должно давать мне отрицательную длительность, или длительность, которая отключена на несколько порядков (выше гранулярности), только потому, что кто-то решил установить системные часы на другое значение. Здесь, что Python docs говорит о "time.time()":

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

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

Edit2: Некоторые исследования показывают, что вы можете получить независимое от системы измерение, которое я хочу в Windows с помощью GetTickCount64(), под Linux вы можете получить его в возвращаемом значении times(). Тем не менее, я до сих пор не могу найти модуль, который предоставляет эту функциональность в Python.

4b9b3361

Ответ 1

То, что вы ищете, - это монотонный таймер. A монотонный отсчет времени не прыгает или не возвращается назад.

Было предпринято несколько попыток реализовать кросс-платформенные монотомные часы для Python на основе ссылки на ОС. (Windows, POSIX и BSD совершенно разные) См. Обсуждения и некоторые попытки монотонного времени в этом сообщении SO.

В основном, вы можете просто использовать os.times():

os.times()

Возвращает 5-битный номер чисел с плавающей запятой, указывающий накопленный (процессор или другой) раз, в секундах. Элементы: время пользователя, системное время, время для детей, время в системе для детей, и истекшее реальное время с фиксированной точки в прошлом, в этом порядке. См. Временные страницы справочной системы Unix (2) или соответствующие окна Windows Документация API платформы. В Windows только первые два элемента заполнены, остальные равны нулю.

Доступность: Unix, Windows

Но это не заполняет необходимое истекшее реальное время (пятый кортеж) в Windows.

Если вам нужна поддержка Windows, рассмотрите ctypes, и вы можете напрямую вызвать GetTickCount64(), как это было сделано в этот рецепт.

Ответ 2

Для измерения прошедшего времени процессора просмотрите time.clock(). Это эквивалент Linux times() поля пользовательского времени.

Для бенчмаркинга используйте timeit.

модуль datetime, который является частью Python 2.3+, также имеет микросекундное время, если поддерживается платформой.

Пример:

>>> import datetime as dt
>>> n1=dt.datetime.now()
>>> n2=dt.datetime.now()
>>> (n2-n1).microseconds
678521
>>> (n2.microsecond-n1.microsecond)/1e6
0.678521
ie, it took me .678521 seconds to type the second n2= line -- slow
>>> n1.resolution
datetime.timedelta(0, 0, 1)
1/1e6 resolution is claimed.

Если вас беспокоит изменение системного времени (от DS → ST), просто проверьте объект, возвращенный datetime.Presumable, системное время может иметь небольшую корректировку от NTP. Это должно быть уменьшено, а исправления применяются постепенно, но ntp sync beats может иметь эффект с очень малыми (миллисекундами или микросекундами) ссылками на время.

Вы также можете ссылаться на функцию Alex Martelli C, если хотите что-то из этого разрешения. Я бы не зашел слишком далеко, чтобы изобретать велосипед. Точное время является основным, и большинство современных ОС выполняют довольно хорошую работу.

Edit

Основываясь на ваших пояснениях, похоже, что вам нужна простая боковая проверка, если системные часы изменились. Просто сравните с дружественным локальным сервером ntp:

import socket
import struct
import time

ntp="pool.ntp.org"   # or whatever ntp server you have handy

client = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
data = '\x1b' + 47 * '\0'
client.sendto( data, ( ntp, 123 ))
data, address = client.recvfrom( 1024 )
if data:
    print 'Response received from:', address
    t = struct.unpack( '!12I', data )[10]
    t -= 2208988800L #seconds since Epoch
    print '\tTime=%s' % time.ctime(t)

NTP является точным до миллисекунд через Интернет и имеет разрешение представления разрешения 2-32 секунды (233 пикосекунды). Должно быть достаточно хорошо?

Помните, что структура данных 64 бит NTP будет переполняться в 2036 году и каждые 136 лет после этого - если вы действительно хотите надежное решение, лучше проверить переполнение...

Ответ 4

>>> import datetime
>>> t1=datetime.datetime.utcnow()
>>> t2=datetime.datetime.utcnow()
>>> t2-t1
datetime.timedelta(0, 8, 600000)

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

Что касается использования альтернативного метода, а не вычитания двух часов, имейте в виду, что ОС фактически содержит часы, которые инициализируются из аппаратных часов на ПК. Современные реализации ОС также будут поддерживать синхронизацию этих часов с некоторым официальным источником, чтобы он не дрейфовал. Это намного более точно, чем любой таймер, который может быть запущен ПК.

Ответ 5

Примеры функций, которые вы укажете в своем редактировании, - это две совершенно разные вещи:

  • Linux times() возвращает время процесса в миллисекундах CPU. Эквивалент Python - time.clock() или os.times().
  • Windows GetTickCount64() возвращает время безотказной работы системы.

Хотя две различные функции, оба (потенциально) могут быть использованы для выявления системных часов, которые имели "отрыжку" с помощью этих методов:

Во-первых:

Вы можете взять системное время с time.time() и время процессора с помощью time.clock(). Поскольку время настенных часов ВСЕГДА будет больше или равно процессорному времени, отбросьте любые измерения, где интервал между двумя показаниями time.time() меньше, чем показания проверки парных time.clock().

Пример:

t1=time.time()
t1check=time.clock()

# your timed event...    

t2=time.time()
t2check=time.clock()

if t2-t1 < t2check - t1check:
    print "Things are rotten in Denmark"
    # discard that sample
else:
    # do what you do with t2 - t1... 

Второе:

Обеспечение бесперебойной работы системы также является многообещающим, если вы обеспокоены системными часами, поскольку пользователь reset в большинстве случаев не считает reset количество отсчетов времени безотказной работы. (что я знаю...)

Теперь более сложный вопрос: получение времени безотказной работы системы независимо от платформы - особенно без появления новой оболочки - на второй секунде. Хммм...

Вероятно, лучший вариант psutil. Просмотр источника, они используют uptime = GetTickCount() / 1000.00f; для Windows и sysctl "kern.boottime" для BSD/OS X и т.д. К сожалению, все они имеют разрешение 1 секунду,

Ответ 6

from datetime import datetime
start = datetime.now()
print 'hello'
end = datetime.now()
delta = end-start
print type(delta)
<type 'datetime.timedelta'>
import datetime
help(datetime.timedelta)
...elapsed seconds and microseconds...