在Python中的str性能
当分析一段python代码( python 2.6
到3.2
)时,我发现把对象(在我的情况下是一个整数)转换为一个string的str
方法几乎比使用string格式化要慢一个数量级。
这是基准
>>> 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
%
与运行时expression式不是(显着)比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
当然,以上是我testing的系统(CPython 2.7); 其他实现可能不同。
我们想到的一个原因是str(100000)
涉及全局查找,但"%s"%100000
不包含。 必须在全球范围内查找全球的情况。 这并没有考虑到整个差异:
>>> 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