views:

640

answers:

2

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().

+9  A: 

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 = 1 # 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, 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()
Armin Ronacher
Wow. Remove "self." and it worked perfectly. Very impressive. It requires ctypes which is add-on for Python 2.4, but it will do quite nicely. Thanks.
Thomas
Oh, and CLOCK_MONOTONIC seems to be 4 on FreeBSD and 1 on Linux.
Thomas
Nice solution. Is there any reason you use ctypes.pointer instead of ctypes.byref?
Kiv
@Thomas: fixed that, removed the self@Kiv: byref should work, can't test that right now, but it should do the trick. I don't remember when byref() does not work, so i went the safe path here.
Armin Ronacher
Could you (or someone else with edit powers) edit this answer and change 10e9 to 1e9 as Mitch suggest in other answer?
Thomas
I added code inspired by this, and actually under use here: http://code.google.com/p/anacrolix/source/browse/projects/pimu/monotime.py
Matt Joiner
+1  A: 

The scaling constant should be 1e9 not 10e9, otherwise the fractional part of the second is only 10% of what it should be.

This is meant as a comment to the answer I assume.
Thomas
Fixed. [padding]
Tobu