Welcome, guest | Sign In | My Account | Store | Cart

This function prints out a message with the elapsed time from the previous call. It works with most Python 2.x platforms. The function uses a simple trick to store a persistent variable (clock) without using a global variable.

Python, 40 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
''' Simple Timing Function.
This function prints out a message with the elapsed time from the 
previous call. It works with most Python 2.x platforms. The function 
uses a simple trick to store a persistent variable (clock) without
using a global variable.
'''
import time
def dur( op=None, clock=[time.time()] ):
    if op != None:
        duration = time.time() - clock[0]
        print '%s finished. Duration %.6f seconds.' % (op, duration)
    clock[0] = time.time()

# Example
if __name__ == '__main__':
    import array
    dur()   # Initialise the timing clock
    
    opt1 = array.array('H')
    for i in range(1000):
        for n in range(1000):
            opt1.append(n)
    dur('Array from append')
    
    opt2 = array.array('H')
    seq = range(1000)
    for i in range(1000):
        opt2.extend(seq)
    dur('Array from list extend')
    
    opt3 = array.array('H')
    seq = array.array('H', range(1000))
    for i in range(1000):
        opt3.extend(seq)
    dur('Array from array extend')

# Output:
# Array from append finished. Duration 0.175320 seconds.
# Array from list extend finished. Duration 0.068974 seconds.
# Array from array extend finished. Duration 0.001394 seconds.

I have been using this timing function for over a decade. I have not seen this technique mentioned elsewhere and I thought it may be useful to other programmers.

I find profiler, hotshot, timeit, etc too complex for quick speed checks. This function has always worked for me. There are some small overheads with the function call, but for timing code that takes milliseconds to seconds it is fine.

2 comments

Adrian Stoica 7 years, 12 months ago  # | flag

I'm pretty new at this so apologies in advance if the question is stupid: How is it that when you call the dur() function it keeps the value of the clock attribute of the previous call of the function instead of assigning by default the new time of the function call?

Mike Sweeney (author) 7 years, 12 months ago  # | flag

Not a stupid question at all. When the dur function is created, the default list for the clock attribute is created and internally linked to the function. This gives us a way to store state inside a function. The time of the last call to dur is kept in the first element of this bound list. This method is more elegant and safe than a global variable, and less trouble than keeping a clock variable in every script that uses the dur function.

Here is a different example of this Python feature. The following function returns the biggest number called so far:

>>> def biggest(n, store=[None]):
...     store[0] = max(n, store[0])
...     return store[0]
... 
>>> biggest(4)
4
>>> biggest(9)
9
>>> biggest(3)
9
>>> biggest(1)
9

I hope that helps.