python中的timeit.timeit()函数的拆解

3 投票
1 回答
511 浏览
提问于 2025-04-17 23:50

有没有办法为Python中的timeit.timeit()函数指定一个清理步骤?我知道有'语句'和'设置'这两个参数,但我还没找到一个好的方法来执行清理。

把清理代码放在我的'语句'里会影响我想要计时的代码片段的时间。我需要一个清理步骤来释放硬件资源,这样我才能使用timeit模块中的重复功能。

1 个回答

1

其实,没有什么特别好的办法来解决这个问题。根据源代码来看,你可能需要创建一个新的类,继承自Timer类,并把他们的self.inner替换成你自己写的版本。

比如:

import inspect
import timeit

class MyTimer(timeit.Timer):
    def __init__(self, stmt="pass", setup="pass", teardown=None, timer=timeit.default_timer):
        timeit.Timer.__init__(self, stmt, setup, timer)
        # Pull the actual function to time off the original `self.inner` function.
        time_func = inspect.getargspec(self.inner).defaults[0]
        # It gets added as a keyword so that lookup in the 
        # current namespace is really fast.
        def _func(_it, _timer, _func=time_func):
            setup()
            total = 0.0
            for _i in _it:
                _t0 = _timer()
                _func()
                _t1 = timer()
                total += _t1 - _t0
                if teardown:
                    teardown()
            return total
        self.inner = _func

不过要注意,这样做的计时效果可能不太好,因为你只能一次计时一个测试。很遗憾,我没有聪明到能找到一个方法,可以在需要为每个测试调用清理函数的情况下,同时计时多个测试。

另外,你也可以对_template_func进行修改,基本上就是在创建计时器之前,把我上面提到的_func复制过来。如果你想尽量做到干净利落,使用mock来进行修改和恢复可能是个好主意(不过你自己动手也不难)。

注意,我们在这里玩的是一些内部的东西——这个答案随时可能会失效,而且可能只在CPython上有效,因为这些内容并没有文档说明。

撰写回答