Here is a handy Python Timer class. It creates a context manager object, used for timing a block of code.
from timeit import default_timer class Timer(object): def __init__(self, verbose=False): self.verbose = verbose self.timer = default_timer def __enter__(self): self.start = self.timer() return self def __exit__(self, *args): end = self.timer() self.elapsed_secs = end - self.start self.elapsed = self.elapsed_secs * 1000 # millisecs if self.verbose: print 'elapsed time: %f ms' % self.elapsed
To use the Timer (context manager object), invoke it using Python's `with` statement. The duration of the context (code inside your `with` block) will be timed. It uses the appropriate timer for your platform, via the `timeit` module.
Timer is used like this:
with Timer() as target: # block of code goes here. # result (elapsed time) is stored in `target` properties.
Example script:
timing a web request (HTTP GET), using the `requests` module.
#!/usr/bin/env python import requests from timer import Timer url = 'https://github.com/timeline.json' with Timer() as t: r = requests.get(url) print 'fetched %r in %.2f millisecs' % (url, t.elapsed)
Output:
fetched 'https://github.com/timeline.json' in 458.76 millisecs
`timer.py` in GitHub Gist form, with more examples:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# | |
# Python Timer Class - Context Manager for Timing Code Blocks | |
# Corey Goldberg - 2012 | |
# | |
from timeit import default_timer | |
class Timer(object): | |
def __init__(self, verbose=False): | |
self.verbose = verbose | |
self.timer = default_timer | |
def __enter__(self): | |
self.start = self.timer() | |
return self | |
def __exit__(self, *args): | |
end = self.timer() | |
self.elapsed_secs = end - self.start | |
self.elapsed = self.elapsed_secs * 1000 # millisecs | |
if self.verbose: | |
print 'elapsed time: %f ms' % self.elapsed | |
if __name__ == '__main__': | |
# example: | |
# 'HTTP GET' from requests module, inside timer blocks. | |
# invoke the Timer context manager using the `with` statement. | |
import requests | |
url = 'https://github.com/timeline.json' | |
# verbose (auto) timer output | |
with Timer(verbose=True): | |
r = requests.get(url) | |
# print stored elapsed time in milliseconds | |
with Timer() as t: | |
r = requests.get(url) | |
print 'response time (millisecs): %.2f' % t.elapsed | |
# print stored elapsed time in seconds | |
with Timer() as t: | |
r = requests.get(url) | |
print 'response time (secs): %.3f' % t.elapsed_secs | |
# example output: | |
# | |
# $ python timer.py | |
# elapsed time: 652.403831 ms | |
# response time (millisecs): 635.49 | |
# response time (secs): 0.624 |
8 comments:
I have something very similar in my utils, but you can also give it a name: https://gist.github.com/2944722
I've been using decorators for this. I'll have to see how hard it would be to add context manager syntax support in profilehooks.
Very cool tool! timeit can be a pain to use, because of it string statement argument.
This seems much more natural to use. Kudos!
I did something similar. I also added an option to append the timings to a CSV, since I was trying to optimize a time sensitive piece of code.
I wasn't aware of default_timer. TIL. :-)
https://gist.github.com/2948552
Thanks!
Very useful timer class, a good use of context manager
https://github.com/jsocol/pystatsd/blob/master/statsd/client.py - similar idea also usable as a decorator.
I am receiving an error in attempting to import the requests module. Is this pseudo-code? From where are your importing this?
@chrisk
you need to install `requests` (a *great* module).
see: http://docs.python-requests.org/
or `pip install requests`
-Corey
Post a Comment