Python:有没有办法使用timeit.timeit()导入变量?

2024-04-26 01:28:19 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一个函数,它接受一个数组并将每个元素更改为0。

def function(array):
    for i in range(0,len(array)):
        array[i] = 0
return array

我想测试这个函数在一个随机数组上运行需要多长时间,我想在时间测试之外生成这个随机数组。换句话说,我不想将生成数组所需的时间包括在时间中。

我首先将随机数组存储在变量x中,然后执行以下操作:

timeit.timeit("function(x)",setup="from __main__ import function")

但这给了我一个错误:name error:未定义全局名称“x”

我该怎么做?


Tags: 函数in元素forlenreturndefsetup
3条回答

__main__导入x

timeit.timeit("function(x)",setup="from __main__ import function, x")

如果向timeit传递函数而不是字符串,则可以完全避免此问题。在这种情况下,函数在其正常的全局和闭包环境中执行。所以:

timeit.timeit(lambda: function(x))

或者,如果您愿意:

timeit.timeit(partial(function, x))

(详见here。注意,它需要Python2.6+,所以如果需要2.3-2.5,就不能使用这个技巧。)


正如文档所说,“注意,在这种情况下,由于额外的函数调用,计时开销稍微大一些。”

这意味着它使timeit本身运行得更慢。例如:

>>> def f(): pass
>>> timeit.timeit('timeit.timeit("f()", setup="from __main__ import f")', setup='import timeit', number=1000)
91.66315175301861
>>> timeit.timeit(lambda: timeit.timeit(f), number=100)
94.89793294097762

但是,这并不影响实际结果:

>>> timeit.timeit(f, number=100000000)
8.81197881908156
>>> timeit.timeit('f()', setup='from __main__ import f', number=100000000)
8.893913001054898

(在极少数情况下,这通常意味着一个或另一个版本没有按照在实际代码中调用函数的方式测试该函数,或者测试了错误的闭包或类似的闭包。)

注意,函数内部的实际时间大约是88秒,所以我们几乎将计时代码的开销增加了一倍……但它仍然只增加了总测试时间的3%。越不重要的是,这种差别就越小。

__main__以及导入x

timeit.timeit("function(x)", setup="from __main__ import function, x")

就像functionx__main__模块中的一个名称,可以导入到timeit设置中。

相关问题 更多 >