Get timer ticks in Python
In the time
module, there are two timing functions: time
and clock
. time
gives you "wall" time, if this is what you care about.
However, the python docs say that clock
should be used for benchmarking. Note that clock
behaves different in separate systems:
- on MS Windows, it uses the Win32 function QueryPerformanceCounter(), with "resolution typically better than a microsecond". It has no special meaning, it's just a number (it starts counting the first time you call
clock
in your process).
# ms windows t0= time.clock() do_something() t= time.clock() - t0 # t is wall seconds elapsed (floating point)
- on *nix,
clock
reports CPU time. Now, this is different, and most probably the value you want, since your program hardly ever is the only process requesting CPU time (even if you have no other processes, the kernel uses CPU time now and then). So, this number, which typically is smaller¹ than the wall time (i.e. time.time() - t0), is more meaningful when benchmarking code:
# linux t0= time.clock() do_something() t= time.clock() - t0 # t is CPU seconds elapsed (floating point)
Apart from all that, the timeit module has the Timer
class that is supposed to use what's best for benchmarking from the available functionality.
¹ unless threading gets in the way…
² Python ≥3.3: there are time.perf_counter()
and time.process_time()
. perf_counter
is being used by the timeit
module.
Here's a solution that I started using recently:
class Timer: def __enter__(self): self.begin = now() def __exit__(self, type, value, traceback): print(format_delta(self.begin, now()))
You use it like this (You need at least Python 2.5):
with Timer(): do_long_code()
When your code finishes, Timer automatically prints out the run time. Sweet! If I'm trying to quickly bench something in the Python Interpreter, this is the easiest way to go.
And here's a sample implementation of 'now' and 'format_delta', though feel free to use your preferred timing and formatting method.
import datetimedef now(): return datetime.datetime.now()# Prints one of the following formats*:# 1.58 days# 2.98 hours# 9.28 minutes # Not actually added yet, oops.# 5.60 seconds# 790 milliseconds# *Except I prefer abbreviated formats, so I print d,h,m,s, or ms. def format_delta(start,end): # Time in microseconds one_day = 86400000000 one_hour = 3600000000 one_second = 1000000 one_millisecond = 1000 delta = end - start build_time_us = delta.microseconds + delta.seconds * one_second + delta.days * one_day days = 0 while build_time_us > one_day: build_time_us -= one_day days += 1 if days > 0: time_str = "%.2fd" % ( days + build_time_us / float(one_day) ) else: hours = 0 while build_time_us > one_hour: build_time_us -= one_hour hours += 1 if hours > 0: time_str = "%.2fh" % ( hours + build_time_us / float(one_hour) ) else: seconds = 0 while build_time_us > one_second: build_time_us -= one_second seconds += 1 if seconds > 0: time_str = "%.2fs" % ( seconds + build_time_us / float(one_second) ) else: ms = 0 while build_time_us > one_millisecond: build_time_us -= one_millisecond ms += 1 time_str = "%.2fms" % ( ms + build_time_us / float(one_millisecond) ) return time_str
Please let me know if you have a preferred formatting method, or if there's an easier way to do all of this!