Skip to content

Instantly share code, notes, and snippets.

@zed
Last active April 15, 2019 09:04
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save zed/5073409 to your computer and use it in GitHub Desktop.
Save zed/5073409 to your computer and use it in GitHub Desktop.
time.process_time() and time.perf_counter() for Python 2 on Ubuntu.
"""time.process_time() and time.perf_counter() for Python 2 on Ubuntu."""
import ctypes
import errno
from ctypes.util import find_library
from functools import partial
CLOCK_PROCESS_CPUTIME_ID = 2 # time.h
CLOCK_MONOTONIC_RAW = 4
clockid_t = ctypes.c_int
time_t = ctypes.c_long
class timespec(ctypes.Structure):
_fields_ = [
('tv_sec', time_t), # seconds
('tv_nsec', ctypes.c_long) # nanoseconds
]
_clock_gettime = ctypes.CDLL(find_library('rt'), use_errno=True).clock_gettime
_clock_gettime.argtypes = [clockid_t, ctypes.POINTER(timespec)]
def clock_gettime(clk_id):
tp = timespec()
if _clock_gettime(clk_id, ctypes.byref(tp)) < 0:
err = ctypes.get_errno()
msg = errno.errorcode[err]
if err == errno.EINVAL:
msg += (" The clk_id specified is not supported on this system"
" clk_id=%r") % (clk_id,)
raise OSError(err, msg)
return tp.tv_sec + tp.tv_nsec * 1e-9
try:
from time import perf_counter, process_time
except ImportError: # Python <3.3
perf_counter = partial(clock_gettime, CLOCK_MONOTONIC_RAW)
perf_counter.__name__ = 'perf_counter'
process_time = partial(clock_gettime, CLOCK_PROCESS_CPUTIME_ID)
process_time.__name__ = 'process_time'
if __name__ == "__main__":
import random
import time
from itertools import repeat
from timeit import Timer, default_timer
print("process_time() doesn't include time.sleep(0.5):")
timers = [default_timer, time.clock, process_time, perf_counter]
start_times = [t() for t in timers]
time.sleep(0.5)
_ = sum(random.random() - f for f in repeat(.5, 1000000))
for start, timer in zip(start_times, timers):
print("\t%-12s %.3g" % (timer.__name__, timer() - start))
# measure overhead
print("overhead (execute `pass` statement):")
n = 10000000
for timer in timers:
t = min(Timer(timer=timer).repeat(number=n)) / n
print("\t%-12s %.2f ns" % (timer.__name__, t*1e9))
@Hubbitus
Copy link

Hubbitus commented Mar 9, 2016

Unfortunately it will not work correctly if you will try measure CPU time for code which use multi-threading. For example sklearn.cross_validation.cross_val_score(n_jobs=2)

@zed
Copy link
Author

zed commented Nov 5, 2016

@Hubbitus: it works the same way time.process_time() and time.perf_counter() do in Python 3. Whether or not it is "correct"; I don't know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment