From: <ti...@co...> - 2009-07-10 17:28:58
|
Author: tismer Date: Fri Jul 10 19:31:49 2009 New Revision: 66168 Modified: psyco/v2/dist/benchmark/psycobench.py (contents, props changed) psyco/v2/dist/benchmark/time_builtins.py (props changed) Log: The last check-in message did not make it, because the diff was too big. Repeating parts of the message here: This is the summary of a couple of month's work on psyco. Lots of things have changed and evolved. This is going to be the 2.0.0 release of psyco at this weekend. Psyco needs another day of tweaking before the release can be called a release. I was just checking in because I promised it too often. This check-in is also not tested in any way, yet. If you'd like to try now, please try. The official announcement will be seen on the python-announce list, soon. Thanks - chris Modified: psyco/v2/dist/benchmark/psycobench.py ============================================================================== --- psyco/v2/dist/benchmark/psycobench.py (original) +++ psyco/v2/dist/benchmark/psycobench.py Fri Jul 10 19:31:49 2009 @@ -1,170 +1,170 @@ -# Do not put a sh-bang line here (to allow different python builds to call the benchmarker). -import os -import sys -if sys.platform.startswith('win'): - from time import clock as time -else: - from time import time -from glob import glob -import psyco -import shelve -import gc - - -FASTREPS = 5 -BASELINE = shelve.open('baseline.shl') - -#2.5 Timing = NamedTuple('Timing', 'module func plaintime psycotime ratio') -# I don't have the energy to back-port this thing to 2.4 CT -class Timing(tuple): - __repr__ = lambda self: '%-15s: %-30s plain: %7.0f/s psyco: %10.0f/s ratio: %6.2f' % self - @property - def module(self): return self[0] - @property - def func(self): return self[1] - @property - def plaintime(self): return self[2] - @property - def psycotime(self): return self[3] - @property - def ratio(self): return self[4] - -DEBUG = False - -def auto_time(f): - """ run f until it has taken approx. 1/4 seconds, then - estimate the number of repetitions needed for one second - """ - _time = time - k = 2 - while 1: - start = _time() - f(k) - stop = _time() - if stop - start >= 0.25: - break - k = 2*k - used = stop - start - res = int(k / used + .5) - # goal is to have at least 5 runs or more - assert res >= 5, ("%s's execution time is too long, " - "would be %d runs, only" % (f.__name__, res)) - return res - -def odd(x): - return x % 2 == 1 - -def median(lis): - l = len(lis) - h = l // 2 - if odd(l): - return lis[h] - else: - return (lis[h] + lis[h+1]) / 2 - -def time_it(plain, compiled, once, unittest): - _time = time - result = [] - for func in (plain, compiled): - loops = [] - run_each = once and 1 or 7 - runs = auto_time(func) - if unittest: - runs = 2 - for i in range(run_each): - if DEBUG: print func, - assert not __in_psyco__ - gc.collect() - start = _time() - func(runs) - stop = _time() - loops.append( runs / (stop - start) ) - if DEBUG: print "%0.5f" % loops[-1] - if DEBUG: print [" %0.5f" % x for x in loops] - result.append(max(loops)) - plainloops, psycoloops = result - - descr = plain.__doc__ or plain.__name__ - if descr.startswith('time_'): - descr = descr[5:] - - return Timing((plain.__module__, descr, plainloops, psycoloops, psycoloops/plainloops)) - -def find_timing_modules(): - return sorted(glob('time_*.py')) - -def time_modules(module_names, once=False, update=False, unittest=False): - version = getattr(psyco, 'where_am_i', 'original psyco') + ' ' + getattr(psyco, 'when_was_i_born', '') - print 'Running new timings with', version - if update: - BASELINE['version'] = version - elif 'version' in BASELINE: - print ' comparing to', BASELINE['version'] - print - - for module_name in module_names: - if module_name.endswith('.py'): - module_name = module_name[:-3] - # the plain functions... - mod = __import__(module_name) - # ..and compiled versions. - class compile_me(object): - pass - compile_me = compile_me() # cannot use a dict proxy - # make sure everything on top-level gets compiled... - psyco.full() - execfile(module_name + '.py', compile_me.__dict__) - # and also everything that will be called. - psyco.bind(compile_me) - psyco.stop() - for varname in dir(mod): - if not varname.startswith('time_'): - continue - plain = getattr(mod, varname) - compiled = getattr(compile_me, varname) - timing = time_it(plain, compiled, once, unittest) - - # print and either update or compare - key = '%s:%s' % (timing.module, timing.func) - if update: - print timing - BASELINE[key] = timing - elif key in BASELINE: - print 'new:', timing - print 'old:', BASELINE[key] - print - else: - print timing - -if __name__ == '__main__': - from optparse import OptionParser - - parser = OptionParser() - parser.add_option("-m", "--modules", action='store_true', dest="modules", - default=False, help="time listed modules") - parser.add_option("-x", "--exclude", action='store_true', dest="exclude", - default=False, help="exclude from listed modules from search") - parser.add_option("-q", "--quick", action='store_true', dest="once", - default=False, help="do each test only once, seven times" - " quicker, but less accurate") - parser.add_option("-t", "--unittest", action='store_true', dest="unittest", - default=False, help="run each bench only one time") - parser.add_option("-u", "--update", action='store_true', dest="update", - default=False, help="update the base set of timings") - parser.add_option("-v", "--verbose", action='store_true', dest="verbose", - default=False, help="print verbose timing output") - opt, args = parser.parse_args() - - if opt.modules: - modules = args - elif opt.exclude: - exclude = set(m for m in args if m.endswith('.py')) + set( - (m + '.py') for m in args if not m.endswith('.py') ) - modules = [m for m in find_timing_modules() if m not in exclude] - else: - modules = find_timing_modules() - - DEBUG = opt.verbose - time_modules(modules, once=opt.once, update=opt.update, - unittest=opt.unittest) - gc.collect() +# Do not put a sh-bang line here (to allow different python builds to call the benchmarker). +import os +import sys +if sys.platform.startswith('win'): + from time import clock as time +else: + from time import time +from glob import glob +import psyco +import shelve +import gc + + +FASTREPS = 5 +BASELINE = shelve.open('baseline.shl') + +#2.5 Timing = NamedTuple('Timing', 'module func plaintime psycotime ratio') +# I don't have the energy to back-port this thing to 2.4 CT +class Timing(tuple): + __repr__ = lambda self: '%-15s: %-30s plain: %7.0f/s psyco: %10.0f/s ratio: %6.2f' % self + @property + def module(self): return self[0] + @property + def func(self): return self[1] + @property + def plaintime(self): return self[2] + @property + def psycotime(self): return self[3] + @property + def ratio(self): return self[4] + +DEBUG = False + +def auto_time(f): + """ run f until it has taken approx. 1/4 seconds, then + estimate the number of repetitions needed for one second + """ + _time = time + k = 2 + while 1: + start = _time() + f(k) + stop = _time() + if stop - start >= 0.25: + break + k = 2*k + used = stop - start + res = int(k / used + .5) + # goal is to have at least 5 runs or more + assert res >= 5, ("%s's execution time is too long, " + "would be %d runs, only" % (f.__name__, res)) + return res + +def odd(x): + return x % 2 == 1 + +def median(lis): + l = len(lis) + h = l // 2 + if odd(l): + return lis[h] + else: + return (lis[h] + lis[h+1]) / 2 + +def time_it(plain, compiled, once, unittest): + _time = time + result = [] + for func in (plain, compiled): + loops = [] + run_each = once and 1 or 7 + runs = auto_time(func) + if unittest: + runs = 2 + for i in range(run_each): + if DEBUG: print func, + assert not __in_psyco__ + gc.collect() + start = _time() + func(runs) + stop = _time() + loops.append( runs / (stop - start) ) + if DEBUG: print "%0.5f" % loops[-1] + if DEBUG: print [" %0.5f" % x for x in loops] + result.append(max(loops)) + plainloops, psycoloops = result + + descr = plain.__doc__ or plain.__name__ + if descr.startswith('time_'): + descr = descr[5:] + + return Timing((plain.__module__, descr, plainloops, psycoloops, psycoloops/plainloops)) + +def find_timing_modules(): + return sorted(glob('time_*.py')) + +def time_modules(module_names, once=False, update=False, unittest=False): + version = getattr(psyco, 'where_am_i', 'original psyco') + ' ' + getattr(psyco, 'when_was_i_born', '') + print 'Running new timings with', version + if update: + BASELINE['version'] = version + elif 'version' in BASELINE: + print ' comparing to', BASELINE['version'] + print + + for module_name in module_names: + if module_name.endswith('.py'): + module_name = module_name[:-3] + # the plain functions... + mod = __import__(module_name) + # ..and compiled versions. + class compile_me(object): + pass + compile_me = compile_me() # cannot use a dict proxy + # make sure everything on top-level gets compiled... + psyco.full() + execfile(module_name + '.py', compile_me.__dict__) + # and also everything that will be called. + psyco.bind(compile_me) + psyco.stop() + for varname in dir(mod): + if not varname.startswith('time_'): + continue + plain = getattr(mod, varname) + compiled = getattr(compile_me, varname) + timing = time_it(plain, compiled, once, unittest) + + # print and either update or compare + key = '%s:%s' % (timing.module, timing.func) + if update: + print timing + BASELINE[key] = timing + elif key in BASELINE: + print 'new:', timing + print 'old:', BASELINE[key] + print + else: + print timing + +if __name__ == '__main__': + from optparse import OptionParser + + parser = OptionParser() + parser.add_option("-m", "--modules", action='store_true', dest="modules", + default=False, help="time listed modules") + parser.add_option("-x", "--exclude", action='store_true', dest="exclude", + default=False, help="exclude from listed modules from search") + parser.add_option("-q", "--quick", action='store_true', dest="once", + default=False, help="do each test only once, seven times" + " quicker, but less accurate") + parser.add_option("-t", "--unittest", action='store_true', dest="unittest", + default=False, help="run each bench only one time") + parser.add_option("-u", "--update", action='store_true', dest="update", + default=False, help="update the base set of timings") + parser.add_option("-v", "--verbose", action='store_true', dest="verbose", + default=False, help="print verbose timing output") + opt, args = parser.parse_args() + + if opt.modules: + modules = args + elif opt.exclude: + exclude = set(m for m in args if m.endswith('.py')) + set( + (m + '.py') for m in args if not m.endswith('.py') ) + modules = [m for m in find_timing_modules() if m not in exclude] + else: + modules = find_timing_modules() + + DEBUG = opt.verbose + time_modules(modules, once=opt.once, update=opt.update, + unittest=opt.unittest) + gc.collect() |