timeit.timeit 变量导入 python

timeit.timeit variable importing in python

我正在尝试使用 timeit.timeit() 来查找执行特定代码行需要多少时间。 问题是这一行包含变量,我需要以某种方式导入它们,所以我的问题是如何导入? 为了更清楚,代码看起来像这样:

def func():
    var1 = 'aaa'
    var2 = 'aab'
    t1 = timeit.timeit('var1==var2', 'from __main__ import ___', number = 10**4) #  here I'm missing what to put after the import

如果我试图在 __main__ 中执行此代码,我将直接使用 'from __main__ import var1, var2' 导入变量 有解决此类问题的方法吗?

timeit.Timer takes a callable 以及要评估的字符串

Changed in version 2.6: The stmt and setup parameters can now also take objects that are callable without arguments. This will embed calls to them in a timer function that will then be executed by timeit(). Note that the timing overhead is a little larger in this case because of the extra function calls.

(另见 source,查找 elif hasattr(stmt, '__call__'):)。

对变量创建闭包并将其传递给 timeit:

def func():
    var1 = 'aaa'
    var2 = 'aab'
    t1 = timeit.timeit(lambda: var1 == var2, number = 10**4)

或等同于:

def func():
    var1 = 'aaa'
    var2 = 'aab'
    def closure():
        return var1 == var2
    t1 = timeit.timeit(closure, number = 10**4)

接受的答案在 pdb 调试器和 class 方法中对我不起作用。有效的解决方案是将变量添加到 globals():

globals()['var1'] = var1
globals()['var2'] = var2
timeit.timeit(lambda: var1 == var2, number = 10**4)

使用 lambda 的已接受答案的解决方案会产生大量开销。与替代品比较,使用设置字符串:

func1 117.3 ms
func2  39.0 ms
func1 116.8 ms
func2  41.6 ms
func1 117.2 ms
func2  35.8 ms

如果你想测量这样一个非常快的代码片段,或者比较多个的时间,你最好不要用这样的函数调用的大开销和它的方差来掩盖它们的执行时间。

产生上述结果的基准代码 (Try it online!):

import timeit

def func1():
    s1 = 'aaa'
    s2 = 'aab'
    return timeit.timeit(lambda: s1 == s2)

def func2():
    setup = '''
s1 = 'aaa'
s2 = 'aab'
'''
    return timeit.timeit('s1 == s2', setup)

for func in [func1, func2] * 3:
    print(func.__name__,
          '%5.1f ms' % (func() * 1e3))