If it won't be simple, it simply won't be. [Hire me, source code] by Miki Tebeka, CEO, 353Solutions

Thursday, June 14, 2007

timeit

Sometimes speed is important. The timeit modules lets you find how fast you are.
from timeit import Timer

def fast_fib(n):
if n < 2:
return 1

a, b = 1, 1
for i in range(n - 1):
a, b = b, a + b

return b

def slow_fib(n):
if n < 2:
return 1

return slow_fib(n - 1) + slow_fib(n - 2)


INDEX = 20
TIMES = 100

fast_timer = Timer("fast_fib(INDEX)", "from __main__ import fast_fib, INDEX")
slow_timer = Timer("slow_fib(INDEX)", "from __main__ import slow_fib, INDEX")

print "slow:", slow_timer.timeit(TIMES) / TIMES
print "fast:", fast_timer.timeit(TIMES) / TIMES
On my machine this gives:

fast: 5.11884689331e-06
slow: 0.00996325016022
However sometimes you to send your function some more complex data, plus you don't want to add too much timing code into the top level of your module.
One way to do it is:
def benchmark():
benchmark.index = 20
timer = Timer("fast_fib(benchmark.index)",
"from __main__ import fast_fib, benchmark")
num_runs = 100

print timer.timeit(num_runs) / num_runs

def main(argv=None):
if argv is None:
import sys
argv = sys.argv

from optparse import OptionParser

parser = OptionParser("usage: %prog [options] MESSAGE")
parser.add_option("--benchmark", help="run benchmark",
dest="benchmark", action="store_true", default=0)

opts, args = parser.parse_args(argv[1:])

if opts.benchmark:
benchmark()
raise SystemExit()

if len(args) != 1:
parser.error("wrong number of arguments") # Will exit

# Do main program stuff here
try:
print fast_fib(int(args[0]))
except ValueError:
raise SystemExit("error: %s - bad number" % args[0])

if __name__ == "__main__":
main()

No comments:

Blog Archive