在分析一段python代码(python 2.63.2)时,我发现

以下是基准

>>> from timeit import Timer
>>> Timer('str(100000)').timeit()
0.3145311339386332
>>> Timer('"%s"%100000').timeit()
0.03803517023435887

有人知道为什么会这样吗?

推荐答案

'%s' % 100000由编译器计算,相当于运行时的一个常数.

>>> import dis
>>> dis.dis(lambda: str(100000))
  8           0 LOAD_GLOBAL              0 (str)
              3 LOAD_CONST               1 (100000)
              6 CALL_FUNCTION            1
              9 RETURN_VALUE        
>>> dis.dis(lambda: '%s' % 100000)
  9           0 LOAD_CONST               3 ('100000')
              3 RETURN_VALUE        

具有运行时表达式的%不会(明显)比str快:

>>> Timer('str(x)', 'x=100').timeit()
0.25641703605651855
>>> Timer('"%s" % x', 'x=100').timeit()
0.2169809341430664

请注意,正如@DietrichEpp所说,str的速度仍然稍慢,这是因为str涉及查找和函数调用操作,而%编译为单个即时字节码:

>>> dis.dis(lambda x: str(x))
  9           0 LOAD_GLOBAL              0 (str)
              3 LOAD_FAST                0 (x)
              6 CALL_FUNCTION            1
              9 RETURN_VALUE        
>>> dis.dis(lambda x: '%s' % x)
 10           0 LOAD_CONST               1 ('%s')
              3 LOAD_FAST                0 (x)
              6 BINARY_MODULO       
              7 RETURN_VALUE        

当然,对于我测试的系统(CPython 2.7),上述情况是正确的;其他实现可能有所不同.

Python-3.x相关问答推荐

"安装serial vs安装psyserial header,"""

如何在python中有效地使用多处理和pytube库来加快下载速度?

循环遍历数据框以提取特定值

如何在输入正确的用户名和密码时添加按钮?

按长度和字母数字对Pandas 数据帧列进行排序

在BaseHTTPRequestHandler中填充和返回列表

向前/向后移动导致移动行的数据不可见

Django 模型类方法使用错误的 `self`

合并两个数据帧并对某些总和进行求和

以特定方式重新排列 pandas 数据框的列

TypeError: issubclass() arg 1 在 Flask 中导入 langchain 时必须是一个类

Jupyter Notebook 拒绝打印一些字符串

Python pandas将单元格值移动到同一行中的另一个单元格

如何在 django 中没有循环的情况下获得前键的前键?

逗号分隔列表的 argparse 操作或类型

Python 3 变量名中接受哪些 Unicode 符号?

Python:在 map 对象上调用列表两次

当 None 被传递时,如何将默认值应用于 python 数据类字段?

没有名为urlparse的模块,但我没有使用 urlparse

使用 python 3.0 的 Numpy