我正在试着给一些代码计时。首先,我使用了计时装饰器:
#!/usr/bin/env python
import time
from itertools import izip
from random import shuffle
def timing_val(func):
def wrapper(*arg, **kw):
'''source: http://www.daniweb.com/code/snippet368.html'''
t1 = time.time()
res = func(*arg, **kw)
t2 = time.time()
return (t2 - t1), res, func.__name__
return wrapper
@timing_val
def time_izip(alist, n):
i = iter(alist)
return [x for x in izip(*[i] * n)]
@timing_val
def time_indexing(alist, n):
return [alist[i:i + n] for i in range(0, len(alist), n)]
func_list = [locals()[key] for key in locals().keys()
if callable(locals()[key]) and key.startswith('time')]
shuffle(func_list) # Shuffle, just in case the order matters
alist = range(1000000)
times = []
for f in func_list:
times.append(f(alist, 31))
times.sort(key=lambda x: x[0])
for (time, result, func_name) in times:
print '%s took %0.3fms.' % (func_name, time * 1000.)
收益率
% test.py
time_indexing took 73.230ms.
time_izip took 122.057ms.
这里我使用了timeit:
% python - m timeit - s '' 'alist=range(1000000);[alist[i:i+31] for i in range(0, len(alist), 31)]'
10 loops, best of 3:
64 msec per loop
% python - m timeit - s 'from itertools import izip' 'alist=range(1000000);i=iter(alist);[x for x in izip(*[i]*31)]'
10 loops, best of 3:
66.5 msec per loop
使用timeit的结果实际上是相同的,但使用计时修饰器时,time_indexing
似乎比time_izip
更快。
造成这种差异的原因是什么?
任何一种方法都应该被相信吗?
如果是,是哪一个?
发布于 2009-10-26 21:10:14
使用timeit。不止一次运行测试会给我带来更好的结果。
func_list=[locals()[key] for key in locals().keys()
if callable(locals()[key]) and key.startswith('time')]
alist=range(1000000)
times=[]
for f in func_list:
n = 10
times.append( min( t for t,_,_ in (f(alist,31) for i in range(n))))
for (time,func_name) in zip(times, func_list):
print '%s took %0.3fms.' % (func_name, time*1000.)
->
<function wrapper at 0x01FCB5F0> took 39.000ms.
<function wrapper at 0x01FCB670> took 41.000ms.
发布于 2015-01-02 12:30:11
使用来自functools
的包装来改进Matt Alcock的答案。
from functools import wraps
from time import time
def timing(f):
@wraps(f)
def wrap(*args, **kw):
ts = time()
result = f(*args, **kw)
te = time()
print 'func:%r args:[%r, %r] took: %2.4f sec' % \
(f.__name__, args, kw, te-ts)
return result
return wrap
在一个示例中:
@timing
def f(a):
for _ in range(a):
i = 0
return -1
调用用@timing
包装的方法f
func:'f' args:[(100000000,), {}] took: 14.2240 sec
f(100000000)
这样做的好处是它保留了原始函数的属性;也就是说,像函数名和docstring这样的元数据被正确地保留在返回的函数中。
发布于 2013-02-28 21:10:30
我会使用计时装饰器,因为你可以使用注释在你的代码中散布计时,而不是让你的代码在计时逻辑上变得混乱。
import time
def timeit(f):
def timed(*args, **kw):
ts = time.time()
result = f(*args, **kw)
te = time.time()
print 'func:%r args:[%r, %r] took: %2.4f sec' % \
(f.__name__, args, kw, te-ts)
return result
return timed
使用装饰器或者使用注释都很容易。
@timeit
def compute_magic(n):
#function definition
#....
或者为要计时的函数重新命名别名。
compute_magic = timeit(compute_magic)
https://stackoverflow.com/questions/1622943
复制相似问题