How do I get monotonic time durations in python?

Viewed 30933

I want to log how long something takes in real walltime. Currently I'm doing this:

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

But that will fail (produce incorrect results) if the time is adjusted while the SQL query (or whatever it is) is running.

I don't want to just benchmark it. I want to log it in a live application in order to see trends on a live system.

I want something like clock_gettime(CLOCK_MONOTONIC,...), but in Python. And preferably without having to write a C module that calls clock_gettime().

5 Answers

That function is simple enough that you can use ctypes to access it:

#!/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()

As pointed out in this question, avoiding NTP readjustments on Linux requires CLOCK_MONOTONIC_RAW. That's defined as 4 on Linux (since 2.6.28).

Portably getting the correct constant #defined in a C header from Python is tricky; there is h2py, but that doesn't really help you get the value at runtime.

Here's how I get monotonic time in Python 2.7:

Install the monotonic package:

pip install monotonic

Then in Python:

import monotonic; mtime = monotonic.time.time #now mtime() can be used in place of time.time()
t0 = mtime()
#...do something
elapsed = mtime()-t0 #gives correct elapsed time, even if system clock changed.

EDIT: check that the above works on your target OS before trusting it. The monotonic library seems to handle clock changes in some OSes and not others.

Related