我想要一些依赖于某些设置的代码。设置代码看起来有点像这样:
>>> b = range(1, 1001)
我想要的代码看起来像这样:
>>> sorted(b)
除了我的代码使用与排序不同的函数。但现在这并不重要。
无论如何,只要我将字符串传递给timeit,我就知道如何计算这段代码:
>>> import timeit
>>> t = timeit.Timer("sorted(b)", "b = range(1, 1001)")
>>> min(t.repeat(3, 100))
如何使用可调用的设置并将其放入stmt可调用的可访问的命名空间中?
换句话说,我如何使用上面的代码执行相同的操作,但使用callables,而不是包含callables的字符串?
顺便提一下,这里更大的目标是重复使用单元测试中的代码来衡量性能:
import unittest
class TestSorting(unittest.TestCase):
def setUp(self):
self.b = range(1, 1001)
def test_sorted(self):
sorted(self.b)
我希望做一点工作。 timeit设置需要创建一个TestSorting实例,并且stmt代码必须以某种方式使用该特定实例。
一旦我理解了如何将时间设置放入与timeit stmt相同的命名空间中,我将研究如何将unittest.TestCase实例转换为可以直接输入timeit.Timer的内容。
马特
答案 0 :(得分:1)
在2.6中,你可以“按照the docs执行”:
在2.6版中更改:
stmt
和setup
参数现在也可以使用 没有可调用的对象 参数。这将嵌入调用 他们在计时器功能中会 然后由timeit()
执行。注意 时间开销有点小 在这种情况下更大,因为 额外的函数调用。
您是否仍在使用旧版本的Python?在这种情况下,我建议使用Python 2.6的timer.py
来源并将它们“反向移植”到您遇到的版本 - 如果该版本为2.5,则应该不会很困难(越来越难以越远)当然,回到过去。我通常不建议将此用于“生产”代码,但对于支持测试,调试,性能测量等的代码来说,这是非常好的。
答案 1 :(得分:1)
我在这里问过这个问题的一个变种,并得到了一个没有解决我问题的答案。我相信我们都没有用Pythonic来表达这个问题。
我不知道这是黑客,解决方法,还是它应该如何完成,但确实有效:
>>> import timeit
>>> b = range(1, 1001)
>>> t = timeit.Timer('sorted(b)', setup='from __main__ import b')
>>> t.repeat(3, 100)
[0.0024309158325195312, 0.0024671554565429688, 0.0024020671844482422]
# was it really running 'sorted(b)'? let's compare'
>>> t = timeit.Timer('pass', setup='from __main__ import b')
>>> t.repeat(3, 100)
[3.0994415283203125e-06, 2.1457672119140625e-06, 1.9073486328125e-06]
# teeny times for 'pass', 'sorted(b)' took more time
我已经读过timeit.py,它的工作原理是构造一个语句,然后使用新的命名空间调用eval(),这些命名空间似乎没有连接到你的主命名空间。请注意,由于sorted
是内置的,timeit.repeat()
内的eval'表达式可以访问该名称;如果是def
,则必须from __main__ import b, myfunc
。
我希望有更多正确的方法来达到目的。