2012-05-10 21 views
87

雖然仿形一塊Python代碼(python 2.6高達3.2),我發現 str方法來轉換的對象(在我的情況的整數)爲字符串是幅度幾乎是順序慢使用字符串格式。STR性能

這裏是基準

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

有誰知道爲什麼是這樣的話? 我錯過了什麼嗎?

+2

那麼''{}'呢?格式(100000)' – wim

+0

這是最慢但最靈活的。 –

回答

104

'%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);其他實現可能不同。

+0

事實上,這看起來是這樣的原因,我只是嘗試自己,字符串格式比'str'快了約5%。謝謝你的回答。沒有理由在任何地方改變代碼:-) –

+2

進一步闡述:'str'是一個可以反彈到除字符串類型以外的名稱,但是字符串格式化 - 即'str .__ mod__'方法 - 不能被替換,允許編譯器進行優化。編譯器在優化方式上並沒有太多的工作,但它的功能比你想象的要多:) –

+4

...以及在這裏學習的教訓是:從不在這些測試中使用文字! – UncleZeiv

14

想到的一個原因是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 
相關問題