Как получить монотонные длительности времени в python?

Я хочу записать, как долго что-то занимает в реальной стене. В настоящее время я делаю это:

startTime = time.time()
someSQLOrSomething()
print "That took %.3f seconds" % (time.time() - startTime)

Но это приведет к сбою (приведет к неправильным результатам), если время будет настроено, когда SQL-запрос (или что-то еще) работает.

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

Я хочу что-то вроде clock_gettime (CLOCK_MONOTONIC,...), но в Python. И предпочтительно без необходимости писать модуль C, который вызывает clock_gettime().

Ответ 1

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

#!/usr/bin/env python

__all__ = ["monotonic_time"]

import ctypes, os

CLOCK_MONOTONIC_RAW = 4 # see <linux/time.h>

class timespec(ctypes.Structure):
    _fields_ = [
        ('tv_sec', ctypes.c_long),
        ('tv_nsec', ctypes.c_long)
    ]

librt = ctypes.CDLL('librt.so.1', use_errno=True)
clock_gettime = librt.clock_gettime
clock_gettime.argtypes = [ctypes.c_int, ctypes.POINTER(timespec)]

def monotonic_time():
    t = timespec()
    if clock_gettime(CLOCK_MONOTONIC_RAW , ctypes.pointer(t)) != 0:
        errno_ = ctypes.get_errno()
        raise OSError(errno_, os.strerror(errno_))
    return t.tv_sec + t.tv_nsec * 1e-9

if __name__ == "__main__":
    print monotonic_time()

Ответ 2

Теперь в Python 3.3 вы будете использовать time.monotonic.

Ответ 3

Как указано в этом вопросе, для предотвращения перенастройки NTP в Linux требуется CLOCK_MONOTONIC_RAW. Это определено как 4 в Linux (начиная с 2.6.28).

Возможность получения правильной константы #defined в заголовке C из Python сложна; есть h2py, но это не помогает вам получить значение во время выполнения.

Ответ 4

time.monotonic() может быть полезно:

Возвращает значение (в дробных секундах) монотонных часов, т.е. часы, которые не могут вернуться назад. Обновление системных часов не влияет на часы. Контрольной точкой возвращаемого значения является undefined, поэтому допустима только разница между результатами последовательных вызовов.