Timeit:以 f 字符串格式传递 stmt 参数

Timeit: pass stmt argument with f-string format

我正在尝试通过 timeit 模块估算 运行 算法的时间。但是我 运行 在用 f-string 传递 stmt 参数时遇到了问题。为了演示我的问题,我创建了两个简单的函数,以 return 斐波那契数作为示例:

def fibo_exponential(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    return fibo(n-1) + fibo(n-2)

def fibo_linear(n):
    List = [0]*3
    List[0] = 0
    List[1] = 1
    for i in range(2,n+1):
        List[2] = List[1] + List[0]
        List[0] = List[1]
        List[1] = List[2]
    return List[2]

from timeit import timeit

def time():
    print(timeit('fibo_linear(10)', 'from __main__ import fibo_linear', number=100000))
    print(timeit('fibo_exponential(10)', 'from __main__ import fibo_exponential', number=100000))
    print(timeit(f"{fibo_linear(10)}", 'from __main__ import fibo_linear', number=100000))
    print(timeit(f"{fibo_exponential(10)}", 'from __main__ import fibo_linear', number=100000))

结果如下图:

time()                # The argument for stmt list below:
0.21902308000426274   # 'fibo_linear(10)'
2.1373995500034653    # 'fibo_exponential(10)'
0.0006944179913261905 # f"{fibo_linear(10)}"
0.0006128590030129999 # f"{fibo_exponential(10)}"

我的问题是为什么使用 f 字符串格式时时间不同?

timeit 获取给定的字符串,并将其计算为 python 代码。

请注意,立即 评估 f 字符串。当你做

f'{fibo_linear(10)}'

fibo_linear(10) 会解析为 55,然后字符串解析为 '55'.

因此,在您的前两个示例中,您告诉 timeit 评估以下行,如 python 代码:

'fibo_linear(10)'
'fibo_exponential(10)'

但是在你的后两个例子中,你告诉它评估这个:

'55'

当然,这几乎是瞬时的。因为它是,你知道的,一个常数。


换句话说,f'{fibo_linear(10)}' == '55'True