File: decorator1.py
""" timer function decorator examples run me under Python 2.6 or 3.0 """ import time class timer: def __init__(self, func): self.func = func self.alltime = 0 def __call__(self, *args, **kargs): start = time.clock() result = self.func(*args, **kargs) elapsed = time.clock() - start self.alltime += elapsed print('%s: %.5f, %.5f' % (self.func.__name__, elapsed, self.alltime)) return result # # caveat: map() returns an iterator in 3.0: use list(map()) to force # it to build a list like the list comprehension does, but don't do # so in 2.6 -- would build two lists, not one; range() is an iterator # in 3.0 too, so results for 2.6 and 3.0 won't compare directly; # if __name__ == '__main__': import sys @timer def listcomp(N): return [x * 2 for x in range(N)] if sys.version_info[0] == 2: @timer def mapcall(N): return map((lambda x: x * 2), range(N)) else: @timer def mapcall(N): return list(map((lambda x: x * 2), range(N))) result = listcomp(5) # time for this call, all calls, return value listcomp(50000) listcomp(500000) listcomp(1000000) print(result) print('allTime = %s' % listcomp.alltime) # total time for all comp calls print('') result = mapcall(5) mapcall(50000) mapcall(500000) mapcall(1000000) print(result) print('allTime = %s' % mapcall.alltime) # total time for all map calls print('map/comp = %s' % round(mapcall.alltime / listcomp.alltime, 3)) ############################################################################ # add constructor arguments def timer(label='', trace=True): class Timer: def __init__(self, func): self.func = func self.alltime = 0 def __call__(self, *args, **kargs): start = time.clock() result = self.func(*args, **kargs) elapsed = time.clock() - start self.alltime += elapsed if trace: format = '%s %s: %.5f, %.5f' values = (label, self.func.__name__, elapsed, self.alltime) print(format % values) return result return Timer if __name__ == '__main__': import sys @timer(trace=True, label='[CCC]==>') def listcomp(N): return [x * 2 for x in range(N)] if sys.version_info[0] == 2: @timer(trace=True, label='[MMM]==>') def mapcall(N): return map((lambda x: x * 2), range(N)) else: @timer(trace=True, label='[MMM]==>') def mapcall(N): return list(map((lambda x: x * 2), range(N))) for func in (listcomp, mapcall): print('') result = func(5) # time for this call, all calls, return value func(50000) func(500000) func(1000000) print(result) print('allTime = %s' % func.alltime) # total time for all calls print('map/comp = %s' % round(mapcall.alltime / listcomp.alltime, 3))