python中的str性能

Posted

技术标签:

【中文标题】python中的str性能【英文标题】:str performance in python 【发布时间】:2012-05-18 19:23:34 【问题描述】:

在分析一段 Python 代码(python 2.63.2)时,我发现 str 将对象(在我的例子中是整数)转换为字符串的方法几乎比使用字符串格式化慢一个数量级。

这是基准

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

有人知道为什么会这样吗? 我错过了什么吗?

【问题讨论】:

那么''.format(100000) 那是最慢但也是最灵活的。 【参考方案1】:

'%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

请注意str 仍然稍慢,正如@DietrichEpp 所说,这是因为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),以上是正确的;其他实现可能会有所不同。

【讨论】:

确实是这个原因,我自己试过了,字符串格式化比str快5%。感谢您的回答。没有理由到处更改代码:-) 进一步详细说明:str 是一个可以重新绑定到字符串类型以外的名称,但字符串格式 - 即 str.__mod__ 方法 - 不能被替换,这允许编译器做优化。编译器在优化方面做的不多,但它做的比你想象的要多:) ...这里要吸取的教训是:永远不要在这样的测试中使用文字! 您可能会对这个特定的博客条目感兴趣:skymind.com/~ocrow/python_string。它包含与您在上面提供的类似的各种字符串连接方法的基准图表。【参考方案2】:

想到的一个原因是str(100000) 涉及全局查找,但"%s"%100000 没有。 str 全局必须在全局范围内查找。这并不能说明全部差异:

>>> Timer('str(100000)').timeit()
0.2941889762878418
>>> Timer('x(100000)', 'x=str').timeit()
0.24904918670654297

thg435 所述,

>>> Timer('"%s"%100000',).timeit()
0.034214019775390625
>>> Timer('"%s"%x','x=100000').timeit()
0.2940788269042969

【讨论】:

以上是关于python中的str性能的主要内容,如果未能解决你的问题,请参考以下文章

Python中的str

python中的strip()方法

Python 3中的str和bytes类型

Python中的字符串方法和str方法有啥区别?

Python中的字符串距离矩阵

python第二十一课——str中的常用函数(重要)