我正在尝试对一些代码进行计时。首先我使用了计时装饰器:
#!/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
快。
是什么造成了这种差异?
这两种方法都应该相信吗?
如果是,是哪一个?
8条答案
按热度按时间pdsfdshx1#
使用
functools
的 Package 来改进Matt Alcock的答案。在示例中:
调用 Package 有
@timing
的方法f
:这样做的优点是它保留了原始函数的属性;也就是说,像函数名和文档字符串这样的元数据被正确地保留在返回的函数上。
a2mppw5e2#
我会使用计时装饰器,因为您可以使用注解在代码周围散布计时,而不是使用计时逻辑使代码变得混乱。
使用装饰器或者使用注解都很容易。
或者重新给你想要计时的函数取别名。
yk9xbfzb3#
使用timeit。多次运行测试会给我好得多的结果。
hkmswyz64#
受到Micah Smith的回答的启发,我直接使用了funcy print(不使用日志模块)。
下面是方便在谷歌可乐使用。
yuvru6vn5#
我厌倦了
from __main__ import foo
,现在使用这个--用于简单的args,%r可以使用,而不是在Ipython中。(Why
timeit
是否只对字符串有效,而不是thunks / closures,即timefunc(f,arbitrary args)?新增:另见“ipython plays weird tricks withmain”,Martelli in running-doctests-through-ipython
uxh89sit6#
这是您希望库提供可移植解决方案的需求类型-- DRY!幸运的是,funcy.log_duration可以解决这个问题。
示例复制自文档:
浏览funcy文档中的其他变体,如不同的关键字参数和
@log_iter_durations
。hs1rzwqc7#
这只是一个猜测,但差异是否可能是range()值差异的数量级?
来自原始来源:
以
timeit
为例:以下是我的系统上的结果,范围设置为100万:
我无法运行您的其他代码,因为我无法在系统上导入“decorator”模块。
更新-当我运行你的代码而不涉及装饰器时,我看到了同样的差异。
感谢您发布此问题;今天学到了一些东西=)
f2uvfpb98#
不管这个特殊的练习,我想使用
timeit
是更安全和可靠的选择。它也是跨平台的,不像你的解决方案。