#!/usr/bin/env python## __COPYRIGHT__## A script for timing snippets of Python code.## By default, this script will execute a single Python file specified on# the command line and time any functions in a list named "FunctionList"# set by the Python file under test, or (by default) time any functions# in the file whose names begin with "Func".## All functions are assumed to get passed the same arguments, and the# inputs are specified in a list named "Data," each element of which# is a list consisting of a tag name, a list of positional arguments,# and a dictionary of keyword arguments.## Each function is expected to test a single, comparable snippet of# of Python code. IMPORTANT: We want to test the timing of the code# itself, not Python function call overhead, so every function should# put its code under test within the following block:## for i in IterationList:## This will allow (as much as possible) us to time just the code itself,# not Python function call overhead.from__future__importdivisionimportgetoptimportsysimporttimeimporttypesUsage="""\Usage: bench.py OPTIONS file.py --clock Use the time.clock function --func PREFIX Test functions whose names begin with PREFIX -h, --help Display this help and exit -i ITER, --iterations ITER Run each code snippet ITER times --time Use the time.time function -r RUNS, --runs RUNS Average times for RUNS invocations of """# How many times each snippet of code will be (or should be) run by the # functions under test to gather the time (the "inner loop").Iterations=1000# How many times we'll run each function to collect its aggregate time# and try to average out timing differences induced by system performance# (the "outer loop").Runs=10# The prefix of the functions under test. This will be used if# there's no explicit list defined in FunctionList.FunctionPrefix='Func'# The function used to get the current time. The default of time.time is# good on most UNIX systems, but time.clock (selectable via the --clock# option) is better on Windows and some other UNIX systems.Now=time.timeopts,args=getopt.getopt(sys.argv[1:],'hi:r:',['clock','func=','help','iterations=','time','runs='])foro,ainopts:ifoin['--clock']:Now=time.clockelifoin['--func']:FunctionPrefix=aelifoin['-h','--help']:sys.stdout.write(Usage)sys.exit(0)elifoin['-i','--iterations']:Iterations=int(a)elifoin['--time']:Now=time.timeelifoin['-r','--runs']:Runs=int(a)iflen(args)!=1:sys.stderr.write("bench.py: only one file argument must be specified\n")sys.stderr.write(Usage)sys.exit(1)exec(open(args[0],'rU').read())try:FunctionListexceptNameError:function_names=sorted([xforxinlocals().keys()ifx[:4]==FunctionPrefix])l=[locals()[f]forfinfunction_names]FunctionList=[fforfinlifisinstance(f,types.FunctionType)]IterationList=[None]*Iterationsdeftimer(func,*args,**kw):results=[]foriinrange(Runs):start=Now()func(*args,**kw)finish=Now()results.append((finish-start)/Iterations)returnresultsdefdisplay(label,results):total=0.0forrinresults:total+=rprint" %8.3f"%((total*1e6)/len(results)),':',labelforfuncinFunctionList:iffunc.__doc__:d=' ('+func.__doc__+')'else:d=''printfunc.__name__+d+':'forlabel,args,kwinData:r=timer(func,*args,**kw)display(label,r)# Local Variables:# tab-width:4# indent-tabs-mode:nil# End:# vim: set expandtab tabstop=4 shiftwidth=4: