# What this gist provides:
tic()
'''code to be timed'''
toc()
#Outputs:
#Elapsed time is: 12.3456 seconds
I often work with huge amounts of data, and processing time can be extensive. I spend a decent chunk of time trying to optimize Python to manage that data efficiently, so I find myself logging script run times quite often. I'm not talking about benchmarking cpu time or anything so precise - instead I'm just curious about how long these algorithms take on the scale of seconds to minutes. I have gotten fed up with adding these little snippets all over my dev code in IPython and the like:
import datetime
start = datetime.datetime.now()
'''
some elegant, complex code that takes a non-trivial amount of
time to run, and you're trying to optimize it
'''
end = datetime.datetime.now()
print start-end
print "This took me %s seconds" %(end-start)
That's a lot of boilerplate code, and just to do something that's crazy simple. I'm sure you could consolidate that down into even fewer lines and keystrokes, but the point remains that you're constantly remembering to import time
or datetime
, save a start/end time variable, and format it into something that is human readable.
I started programming in the Matlab world, and engineers at Mathworks try hard to keep your keystrokes at a minimum. I loved the simplicity of Matlab's tic
and toc
helpers to just to give me a quick gut check of how long a whole process was taking, or even to track overlapping subprocesses within a program. In Matlab, one would just:
tic
% Timed code block
toc
And out came Elapsed time: 48.23412 seconds
. Crazy simple, effective, and doesn't require ANY thought. We can do that! But Matlab also allowed you to overlap tic
s and toc
s, so that one could track elapsed time of separate features within one script or program. Well, if I've learned anything from numpy and matplotlib, it's "Anything Matlab can do, Python can do better".
So, with that mantra in mind, I wrote this code one day after work. Implemented in tic-toc-python.py is the basic code to do all of the above. I realize this code is no revelation and no great shakes, but it's super simple and saves you some valuable time. I suggest just downloading this gist and placing the functions somewhere in a .py file you can import from all your scripts. For what its worth, I have a helpers.py
file at the top level of my main repo where I put little global functions like this one.
# Most basic usage - please tell me how long this took
tic()
''' Code to be timed '''
toc()
And out will come Elapsed time: 4.2323 seconds
, with max 4 trailing decimals. Just like Matlab. I feel so at home, and MAN so easy. No clutter, no remembering what you saved the start time as, no formatting thought. If you're timing something especially long-running, you might even set the fmt kwarg:
tic()
''' super long running script '''
toc(fmt=True)
#OUTPUT
#Elapsed time: 01:13:84
And out will come Elapsed time: 01:13:84
formatted all pretty. If you need to save the time output for some particular reason, you can pass the kwarg 'save':
tic()
''' code to test '''
runtime = toc(save=True)
And you'll get the elapsed time in seconds. Just as in Matlab, we can also overlap multiple timings. But, even BETTER than in Matlab, we can refer to diffent tics and tocs by easy-to-remember tags like so:
tic(tag='load')
''' code that loads a lot of files or downloads stuff from the web, whatever '''
tic(tag='process')
''' code that does something different you want to track '''
# Let's say the downloading is done now
toc(tag='load')
# but maybe the processing doesn't finish till here
toc(tag='process')
#OUTPUT
# load - Elapsed Time: 1234.123456 seconds
# process - Elapsed Time: 1234.123456 seconds
Used as above, the time between the tag='load'
and tag='process'
will be timed separately and printed out separately for each process. Once again, you can combine other args for save
or fmt
to your pleasure.
It's also not hard to envision how you could quickly change the default functionality of tic toc to whatever you please. The idea here is to just provide a Super Simple method of timing code; it's nothing Python doesn't already provide. But I, for one, think that Python can learn a thing or two from Matlab. There's nothing wrong with abstracting a few things for simplicity's sake, and to save you the same keystrokes over and over.
time.time()
is not monotonic and must not be used to measure time intervals