Python 什么';拆包收集的费用是多少?
我正在测量不同函数的运行时间,这些函数使用不同数量的参数。我不想分别为每个函数编写度量代码,而是想将所有内容整合到一个函数中。因为每个要度量的函数都有不同数量的参数,所以我认为解包会很有帮助 代码如下:Python 什么';拆包收集的费用是多少?,python,collections,Python,Collections,我正在测量不同函数的运行时间,这些函数使用不同数量的参数。我不想分别为每个函数编写度量代码,而是想将所有内容整合到一个函数中。因为每个要度量的函数都有不同数量的参数,所以我认为解包会很有帮助 代码如下: import resource def resource_runtime_unpack(f, repeats, args): """ Measures running time of a function using the resource module. Inde
import resource
def resource_runtime_unpack(f, repeats, args):
"""
Measures running time of a function using the resource module.
Index 0 is user time, index 1 is the system time.
Unpacks a list of arguments into the function.
"""
start = resource.getrusage(resource.RUSAGE_SELF)
for i in xrange(repeats):
f(*args)
end = resource.getrusage(resource.RUSAGE_SELF)
return (end.ru_utime - start.ru_utime,
end.ru_stime - start.ru_stime)
每次迭代的参数都会被解包,所以它会反映在结果中,这让我想:解包的成本是多少 您可以自己测量,使用: 因此,是的,解包参数的成本随着参数数量的增加而增加。上面的计时是每100万次调用一次,因此一个包含10个参数的列表解包为一个包含0个参数的列表所需的时间大约是它的两倍
然而,这种开销很小;如果
noop()
做了实际的工作,而不仅仅是一个空函数,那么解包的成本将是整个函数时间的一小部分。@MartijnPieters是成本常量,那么?无论解包的集合的大小如何,Python都会使用用于调用的,因此从计算循环来看,成本是恒定的。然后,用于调用函数的C代码根据序列创建一个元组,并根据该元组更新参数序列。它的成本与参数列表成比例,但这完全是用C代码实现的。与你的代码所做的其他事情相比,这一成本将变得一文不值。如果不考虑这一点,成本比我想象的要大,我会给出一个答案。我不认为巨大的开销必然来自解包,但更多的是来自你的noop
函数的变量*args
的打包。将您的时间与以下内容进行比较:timeit.timeit('noop({})'format(','.join(itertools.repeat('None',100)),'from uuu main_uuuuu.import noop')
@poke:也许应该使用包含那么多参数的函数重新运行计时。压缩回noop()
函数的*args
参数中的参数确实可能是一个因素。@poke:我在noop()
函数中消除了变量参数计数,计时没有太大变化。
>>> import timeit
>>> def variable_args_factory(n):
... template = 'def noop({}): pass'
... args = ', '.join(['arg{}'.format(i) for i in xrange(n)])
... namespace = {}
... exec(template.format(args), namespace)
... return namespace['noop']
...
>>> timeit.timeit('noop()', 'from __main__ import variable_args_factory; noop = variable_args_factory(0)')
0.08463001251220703
>>> timeit.timeit('noop(*args)', 'from __main__ import variable_args_factory; noop = variable_args_factory(0); args = []')
0.11967301368713379
>>> timeit.timeit('noop(*args)', 'from __main__ import variable_args_factory; noop = variable_args_factory(10); args = [None] * 10')
0.22447800636291504
>>> timeit.timeit('noop(*args)', 'from __main__ import variable_args_factory; noop = variable_args_factory(100); args = [None] * 100')
1.5113048553466797
>>> timeit.timeit('noop(*args)', 'from __main__ import variable_args_factory; noop = variable_args_factory(1000); args = [None] * 1000')
12.78959608078003