我在玩f-string(参见PEP 498),我决定判断f-string解析的速度(例如f"{1}"),与通常的str解析(例如str(1))进行比较.但令我惊讶的是,当我用timeit函数判断这两种方法的速度时,我发现

>>> 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,但现在,我有点困惑,有什么 idea 吗?提前谢谢!

PD:如果有人想知道:

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

推荐答案

简单的答案是,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)

当您查看100的反汇编字节码时,行为上的差异是显而易见的.

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-strings肯定没有的开销——至少在本例中,因为不需要eval'd.

Python-3.x相关问答推荐

数组列的极点成对求和

Python多处理池:缺少一个进程

如何将多个字典合并到一个列中,并为不同的行使用相同的键

我不能使用拆分来分隔数据

新行是pandas数据帧中旧行的组合

使用 Fetch 提交表单到 Django 视图

如何将函数映射到所有命名元组的元素?

如何从形状汇总图中提取实际值

通过点和线计算CV2 Homography

是否可以将多个 if 转换为数组?

理解 Keras 的 ImageDataGenerator 类中的 `width_shift_range` 和 `height_shift_range` 参数

如何用pymongo连接远程mongodb

创建日志(log)文件

cv2 python 没有 imread 成员

如何使用 asyncio 添加连接超时?

无 Python 错误/错误?

如何在继承的数据类中创建可选字段?

SQLAlchemy:如果不存在则创建模式

如何为 Python 3.x 安装 psycopg2?

在 Meta 中创建具有动态模型的通用序列化程序