38. timer
— Timer class.¶
-
class
timer.
Timer
(tag='Timer', *, dec=6, start=None, auto=False, acc=None)[source]¶ A class for measuring elapsed time.
The Timer class is a conventient way to measure and report the elapsed time during some processing. It uses Python’s
time.perf_counter()
, providing the highest resolution available.A Timer instance can be used as a context manager, with automatic reading and even reporting the time spent in the context block. Timers can also remember any number of measured timings and report them later.
The Timer value is a floating point value giving a number of seconds elapsed since some undefined reference point. By default this is the moment of creation of the Timer, but the starting point can be set at any time.
Parameters: - tag (str, optional) – A label identifying the current measurement. It is used as the key to store the value in the Timer memory, and it is printed out together with the value when printing the Timer.
- dec (int, optional) – The number of decimals that will be shown or remembered. The default (6) provides microsecond accuracy, which is more than enough for all purposes.
- start (float, optional) – The starting time of the Timer. If provided, it is normally a value
obtained from another Timer instance or from
time.perf_counter()
. If not provided, the time of the initialization of the Timer is used. - auto (bool, optional) – If True, the value of the Timer will be printed on exit of the context manager. Also, the default value for acc becomes False. This is very convenient to quickly do timing to some code block. See Examples.
- acc (bool, optional) – If True, values read from the Timer are accumulated under the tag
value. If False, the read value overwrites the value under the tag.
The default is True if
acc
is False, and False isacc
is True.
Examples
The examples use
time.sleep()
to provide a code block with some known execution time.>>> from time import sleep
The Timer class acts as a context manager, so it can be used in a with statement. This is the recommended way to use the Timer. It measures the time spent in the block inside the with clause.
>>> t = Timer() >>> with t: ... sleep(0.2) >>> print(t) Timer: 0.20... sec.
Printing out the Timer value after measurement is so common, that there is an option to do it automatically. Just set the auto mode on (it can also be done at instantiation time):
>>> t.auto = True >>> sleep(0.05) >>> with t: ... sleep(0.12) Timer: 0.32... sec.
Notice that the Timer accumulated the measured time with the previous. This is the default.You can avoid the accumulation by using separate tags for the measurements.
>>> with t.tag('New tag'): sleep(0.23) New tag: 0.23... sec.
Without a tag, the measurement is accumulated to the last specified tag: >>> with t: sleep(0.15) New tag: 0.38… sec.
You can switch off accumulation completely if you want to:
>>> t1 = Timer(dec=2, auto=True, acc=False) >>> with t1: sleep(0.06) Timer: 0.06 sec. >>> with t1: sleep(0.09) Timer: 0.09 sec.
The Timer remembers the last value (accumulated or not) for each of the tags that was used. This is very convenient to do a series of measurements and then print the Timer
report()
:>>> print(t.report()) Timer: 0.32... sec. New tag: 0.38... sec.
If you want to process the readings in another way, you can access them from the Timer memory, which is a dict with the tags a keys:
>>> print(t.mem) {'Timer': 0.32..., 'New tag': 0.38...}
The last memory item (the one with the current tag) is also available:
>>> print(t.last) New tag: 0.38... sec.
All Timers keep incrementing at the same pace (that of the unique Python
time.perf_counter()
counter). So you may think that using a single Timer with different tags may suffice. However, to do nested measurements with the context manager, you have to use multiple Timers, because our context manager is currently not reentrant. So, the following doesn’t work:>>> with Timer("Outer block") as t: ... sleep(0.08) ... with t.tag("Inner block"): sleep(0.12) ... sleep(0.07) ... with t.tag("Inner block 2"): sleep(0.17) ... sleep(0.06) ... >>> print(t.report()) Inner block: 0.12... sec. Inner block 2: 0.40... sec.
See how the timings from the outer block are added to the “Inner block 2” tag and there is no “Outer block” result at all. The correct way to do nested measurement is using multiple Timers:
>>> with Timer("Outer block") as t: ... sleep(0.08) ... with Timer("Inner block") as t1: sleep(0.12) ... sleep(0.07) ... with t1.tag("Inner block 2"): sleep(0.05) ... sleep(0.06) ... >>> print(t1.report()) Inner block: 0.12... sec. Inner block 2: 0.05... sec. >>> print(t.report()) Outer block: 0.38... sec.
There may be times when the use of a context manager is not useful or even possible (like when the start and end of measurement are in different functions). Then you can always use the low level interface.
The measurement is always done with the
read()
method. It measures and returns the time since the lastreset()
or the creation of the Timer. Here is an example:>>> t = Timer(dec=2) >>> sleep(0.03) >>> v = t.read() >>> sleep(0.05) >>> t.reset() >>> sleep(0.07) >>> v1 = t.read() >>> print(v, v1) 0.03... 0.07...
As we use a single tag, the memory shows the accumulated result:
>>> print(t.mem) {'Timer': 0.10...}
You can have a peek at the current value of the timer, without actually reading it:
>>> sleep(0.07) >>> t.value 0.14... >>> print(t.last) Timer: 0.1 sec.
Any read will however update the current tag:
>>> v = t.read() >>> print(v) 0.14... >>> print(t.last) Timer: 0.24 sec.
When not explicitely calling
read()
(like when using the context manager), you can still get the last value read:>>> print(t.lastread) 0.14...
-
reset
(tag=None, *, start=None)[source]¶ (Re)Start the timer and optionally changes the tag.
Parameters: Returns: Timer – Returns self so that one can use the reset directly in a with statement. See examples.
-
read
(tag=None, *, reset=False)[source]¶ Read the timer.
Parameters: reset (bool, optional) – If True, the Timer is reset after reading, thus the next read will measure from this point. Returns: float – The elapsed time in seconds since the last reset or since the creation of the Timer if there hasn’t been a reset.
-
value
¶ Return the current value of the Timer without reading it.
Returns: float – The current value of the Timer. This value is not stored.
-
lastread
¶ Return the value of the last read rounded to the Timer accuracy
-
format
(tag=None)[source]¶ Return the formatted last read valuefor the specified tag.
Returns: string – The value of the last read()
operation on the Timer (whether explicitly called or implicitly from the context manager), or None if the Timer hasn’t been read yet.
-
last
¶ Print the formatted value of the last used tag