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().
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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()
Method 2
Now, in Python 3.3 you would use time.monotonic.
Method 3
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.
Method 4
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.
Method 5
time.monotonic() might be useful:
Return the value (in fractional seconds) of a monotonic clock, i.e. a clock that cannot go backwards. The clock is not affected by system clock updates. The reference point of the returned value is undefined, so that only the difference between the results of consecutive calls is valid.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0