Насколько глобально точна функция time.time Python? [Дубликат]

Есть ли способ измерить время с высокой точностью в Python - точнее, чем на одну секунду? Я сомневаюсь, что это кросс-платформенный способ сделать это; Мне интересно в режиме высокой точности в Unix, в частности Solaris, работающем на машине Sun SPARC.

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

33
задан fuad 21 December 2009 в 04:41
поделиться

9 ответов

Стандартная функция time.time() обеспечивает точность в секунду, хотя эта точность зависит от платформы. Для точности Linux и Mac +- 1 микросекунда или 0,001 миллисекунды. Python в Windows использует +- точность в 16 миллисекунд из-за проблем с выполнением синхронизации из-за прерываний процесса. Модуль timeit может обеспечить более высокое разрешение, если вы измеряете время выполнения.

>>> import time
>>> time.time()        #return seconds from epoch
1261367718.971009      

Python 3.7 вводит новые функции в модуль time, которые обеспечивают более высокое разрешение:

>>> import time
>>> time.time_ns()
1530228533161016309
>>> time.time_ns() / (10 ** 9) # convert to floating-point seconds
1530228544.0792289
37
ответ дан daf 19 August 2018 в 06:51
поделиться
  • 1
    Обратите внимание, что в Windows время.time () имеет точность ~ 16 миллисекунд. – alexanderlukanin13 16 December 2011 в 12:24
  • 2
    Сколько задержка в получении этого времени? Это точно? – Coderaemon 21 May 2015 в 10:24
  • 3
    неточно в окнах (бесполезно) – Szabolcs Dombi 21 August 2017 в 12:47
  • 4
    Я думаю, что в вашем коде есть опечатка. Я считаю, start2 должен начинаться. И пробел до миллисекунды может помочь читаемости ;-) – Rien Heuver 14 December 2017 в 20:30

Комментарий , оставленный tiho 27-27 марта в 17:21 , заслуживает собственного ответа:

Чтобы избежать кода, специфичного для платформы, use timeit.default_timer ()

2
ответ дан 3 revs 19 August 2018 в 06:51
поделиться

Python 3.7 вводит 6 новых функций времени с разрешением наносекунд , например, вместо time.time() вы можете использовать time.time_ns() :

import time
print(time.time())
# 1522915698.3436284
print(time.time_ns())
# 1522915698343660458

Эти 6 функций описаны в PEP 564 :

time.clock_gettime_ns(clock_id)

time.clock_settime_ns(clock_id, time:int)

time.monotonic_ns()

time.perf_counter_ns()

time.process_time_ns()

time.time_ns()

Эти функции аналогичны версия без суффикса _ns, но возвращает число наносекунд как int Python.

2
ответ дан Chris_Rands 19 August 2018 в 06:51
поделиться
  • 1
    Было бы интересно увидеть этот показатель на малине Pi 3. – SDsolar 7 June 2018 в 17:31
  • 2
    @SDsolar Я планирую попробовать это завтра (хотя, возможно, на Pi2) – Chris H 16 July 2018 в 15:52

Сообщение Дэвида пыталось показать, какое разрешение часов в Windows. Я был смущен его выходом, поэтому я написал код, который показывает, что time.time() на моем ноутбуке Windows 8 x64 имеет разрешение 1 мс:

# measure the smallest time delta by spinning until the time changes
def measure():
    t0 = time.time()
    t1 = t0
    while t1 == t0:
        t1 = time.time()
    return (t0, t1, t1-t0)

samples = [measure() for i in range(10)]

for s in samples:
    print s

Какие выходы:

(1390455900.085, 1390455900.086, 0.0009999275207519531)
(1390455900.086, 1390455900.087, 0.0009999275207519531)
(1390455900.087, 1390455900.088, 0.0010001659393310547)
(1390455900.088, 1390455900.089, 0.0009999275207519531)
(1390455900.089, 1390455900.09, 0.0009999275207519531)
(1390455900.09, 1390455900.091, 0.0010001659393310547)
(1390455900.091, 1390455900.092, 0.0009999275207519531)
(1390455900.092, 1390455900.093, 0.0009999275207519531)
(1390455900.093, 1390455900.094, 0.0010001659393310547)
(1390455900.094, 1390455900.095, 0.0009999275207519531)

И способ сделать 1000 выборок среднего значения дельта:

reduce( lambda a,b:a+b, [measure()[2] for i in range(1000)], 0.0) / 1000.0

Какой вывод на двух последовательных прогонах:

0.001
0.0010009999275207519

Итак time.time() на моем Windows 8 x64 имеет разрешение 1 мс.

Аналогичный прогон на time.clock() возвращает разрешение 0,4 микросекунды:

def measure_clock():
    t0 = time.clock()
    t1 = time.clock()
    while t1 == t0:
        t1 = time.clock()
    return (t0, t1, t1-t0)

reduce( lambda a,b:a+b, [measure_clock()[2] for i in range(1000000)] )/1000000.0

Возвраты:

4.3571334791658954e-07

Который ~ 0.4e-06

Интересно, что в time.clock() он возвращает время с момента вызова метода, поэтому, если вы хотите настенное время на микросекундном разрешении, вы можете сделать что-то вроде этого :

class HighPrecisionWallTime():
    def __init__(self,):
        self._wall_time_0 = time.time()
        self._clock_0 = time.clock()

    def sample(self,):
        dc = time.clock()-self._clock_0
        return self._wall_time_0 + dc

(что, вероятно, заскочит через некоторое время, но вы можете исправить это иногда, например, dc > 3600 будет исправлять его каждый час)

17
ответ дан cod3monk3y 19 August 2018 в 06:51
поделиться
  • 1
    это отличная работа cod3 monk3y ... спасибо, что поделились! – ojblass 17 April 2014 в 15:00
  • 2
    В Windows time.clock измеряет прошедшее время до высокой точности. В OS X и Linux он измеряет время процессора. Начиная с Python 3.3, устарел в пользу perf_counter для измерения прошедшего времени и process_time для измерения CPU. – George 9 June 2016 в 03:51

Я заметил, что разрешение time.time () отличается от версий Windows 10 Professional и Education.

На машине с Windows 10 Professional разрешение составляет 1 мс. На компьютере с системой Windows 10 разрешение составляет 16 мс.

Я нахожу, что это искусственное ограничение довольно красноречиво (и даже неэтично), особенно если оно не включено в сравнительную документацию Windows, опубликованную Microsoft.

1
ответ дан dbdq 19 August 2018 в 06:51
поделиться

Если Python 3 является опцией, у вас есть два варианта:

  • time.perf_counter , которые всегда используют самые точные часы на вашей платформе. Он включает время, затраченное вне процесса.
  • time.process_time , который возвращает время процессора.

Различие между двумя может быть показано с помощью:

from time import (
    process_time,
    perf_counter,
    sleep,
)

print(process_time())
sleep(1)
print(process_time())

print(perf_counter())
sleep(1)
print(perf_counter())

Какие выходы:

0.03125
0.03125
2.560001310720671e-07
1.0005455362793145
7
ответ дан ereOn 19 August 2018 в 06:51
поделиться

Python пытается использовать самую точную функцию времени для вашей платформы для реализации time.time():

/* Implement floattime() for various platforms */

static double
floattime(void)
{
    /* There are three ways to get the time:
      (1) gettimeofday() -- resolution in microseconds
      (2) ftime() -- resolution in milliseconds
      (3) time() -- resolution in seconds
      In all cases the return value is a float in seconds.
      Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
      fail, so we fall back on ftime() or time().
      Note: clock resolution does not imply clock accuracy! */
#ifdef HAVE_GETTIMEOFDAY
    {
        struct timeval t;
#ifdef GETTIMEOFDAY_NO_TZ
        if (gettimeofday(&t) == 0)
            return (double)t.tv_sec + t.tv_usec*0.000001;
#else /* !GETTIMEOFDAY_NO_TZ */
        if (gettimeofday(&t, (struct timezone *)NULL) == 0)
            return (double)t.tv_sec + t.tv_usec*0.000001;
#endif /* !GETTIMEOFDAY_NO_TZ */
    }

#endif /* !HAVE_GETTIMEOFDAY */
    {
#if defined(HAVE_FTIME)
        struct timeb t;
        ftime(&t);
        return (double)t.time + (double)t.millitm * (double)0.001;
#else /* !HAVE_FTIME */
        time_t secs;
        time(&secs);
        return (double)secs;
#endif /* !HAVE_FTIME */
    }
}

(из http://svn.python.org/view/python /trunk/Modules/timemodule.c?revision=81756&view=markup)

19
ответ дан Joe Koberg 19 August 2018 в 06:51
поделиться

Вы также можете использовать time.clock () Он подсчитывает время, используемое процессом в Unix, и время со времени первого вызова на него в Windows.

Это обычно используемая функция для измерения производительности.

Просто позвоните

import time
t_ = time.clock()
#Your code here
print 'Time in function', time.clock() - t_

EDITED: Ups, I пропустите вопрос, как вы хотите точно знать время, а не время, потраченное ...

13
ответ дан kynan 19 August 2018 в 06:51
поделиться

time.clock() имеет 13 десятичных знаков в Windows, но только два в Linux. time.time() имеет 17 десятичных знаков в Linux и 16 в Windows, но фактическая точность отличается.

Я не согласен с документацией, что time.clock() следует использовать для бенчмаркинга на Unix / Linux. Это не достаточно точно, поэтому используемый таймер зависит от операционной системы.

В Linux временное разрешение в time.time() велико:

>>> time.time(), time.time()
(1281384913.4374139, 1281384913.4374161)

В Windows, однако, функция времени, по-видимому, использует последний вызываемый номер:

>>> time.time()-int(time.time()), time.time()-int(time.time()), time.time()-time.time()
(0.9570000171661377, 0.9570000171661377, 0.0)

Даже если я пишу вызовы на разных строках в Windows, он все равно возвращает то же значение, поэтому реальная точность ниже.

Таким образом, при серьезных измерениях необходимо выполнить проверку платформы (import platform, platform.system()), чтобы определить, следует ли использовать time.clock() или time.time().

(Протестировано в Windows 7 и Ubuntu 9.10 с помощью python 2.6 и 3.1)

4
ответ дан livibetter 19 August 2018 в 06:51
поделиться
  • 1
    Конечно, это не значит, что он возвращает последнее значение, но вы делаете несколько вызовов за более короткий промежуток времени, чем разрешение часов. – daf 31 January 2013 в 03:48
  • 2
    Ваш код для Linux отличается от вашего кода для окон. Код Linux показывает кортеж двух значений времени, а ваш код Windows показывает только дробные части и дельта. Результат аналогичного кода будет проще сравнивать. Если этот код показывает все, это значит, что ваш Linux-блок имеет разрешение 2,2 микросекунды time.time() или что ваши вызовы Linux занимают некоторое время (ящик очень медленный, поймал таймер при переходе и т. Д.). Я отправлю код, который показывает способ решения вопроса, который вы здесь задали. – cod3monk3y 23 January 2014 в 07:50
  • 3
    Чтобы избежать кода, специфичного для платформы, используйте timeit.default_timer () – tiho 27 March 2014 в 19:21
Другие вопросы по тегам:

Похожие вопросы: