【问题标题】:Why are f-strings faster than str() to parse values?为什么 f-strings 解析值比 str() 快?
【发布时间】:2019-10-28 11:30:24
【问题描述】:

我在玩 f-strings(请参阅PEP 498),我决定检查 f-string 解析的速度(例如 f"{1}")与通常的 str 解析(例如 str(1))相比)。但令我惊讶的是,当我使用timeit 函数检查这两种方法的速度时,我发现 f-strings 更快。

>>> from timeit import timeit
>>> timeit("f'{1}'")
0.1678762999999961

>>> timeit("str(1)")
0.3216999999999999

甚至是 repr func,在大多数情况下比 str cast 更快

>>> timeit("repr(1)")
0.2528296999999995

我想知道这是为什么?我以为 f 字符串在内部调用 str ,但现在,我有点困惑,有什么想法吗?提前致谢!

PD:如果有人想知道:

assert f"{1}" == str(1) == repr(1)

【问题讨论】:

标签: python python-3.x python-internals f-string


【解决方案1】:

简单的答案是因为f-strings are part of the language's grammar and syntax. 另一方面,str() 调用需要符号表查找,然后是函数调用。

这是一个插入整数变量的类似示例,将其与常量值插值进行对比。

x = 1

%timeit f'{1}'
%timeit f'{x}'
%timeit str(1)
%timeit str(x)

113 ns ± 2.25 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
166 ns ± 4.71 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
342 ns ± 23.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
375 ns ± 11.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

当您使用 dis 查看反汇编的字节码时,行为上的差异很明显。

import dis

dis.dis("f'{x}'")
  1           0 LOAD_NAME                0 (x)
              2 FORMAT_VALUE             0
              4 RETURN_VALUE

dis.dis("str(x)")
  1           0 LOAD_NAME                0 (str)
              2 LOAD_NAME                1 (x)
              4 CALL_FUNCTION            1
              6 RETURN_VALUE

繁重的工作都在 CALL_FUNCTION 指令中,这是 f 字符串肯定没有的开销——至少在这种情况下,因为不需要 eval'd。

【讨论】:

    猜你喜欢
    • 2023-02-10
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    • 2018-01-04
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多