2012-05-11 137 views
3

轉換爲整數時,到其字節字符表示要具體,我需要轉換爲整數,說9999,成字節,b'9999'在Python 2.6可達蟒蛇3.X性能蟒蛇

在蟒蛇2.X我做

b'%s'%n 

而在Python 3.X

('%s'%n).encode() 

性能在Python 2.6

>>> from timeit import Timer 
>>> Timer('b"%s"%n','n=9999').timeit() 
0.24728001750963813 

在python 3.2

>>> from timeit import Timer 
>>> Timer('("%s"%n).encode()','n=9999').timeit() 
0.534475012767416 

假設我的基準性能被正確設置,即在python 3.x的一個沉重的懲罰

有沒有一種方法來提高性能來彌補2.6/2.7的差距?

也許通過cython路線?

這是我試圖優化的生成器函數。它與args是一個字符串列表叫了個遍,字節或數字:

def pack_gen(self, args, encoding='utf-8'): 
    crlf = b'\r\n' 
    yield ('*%s\r\n'%len(args)).encode(encoding) 
    for value in args: 
     if not isinstance(value, bytes): 
      value = ('%s'%value).encode(encoding) 
     yield ('$%s\r\n'%len(value)).encode(encoding) 
     yield value 
     yield crlf 

的函數被調用以這種方式

b''.join(pack_gen(args)) 
+1

爲什麼它需要是字節? –

+2

這是一個巨大的懲罰,因爲你需要先將它轉換爲字符串,然後再轉換爲字節。我沒有看到解決辦法。問題在於它是否真的有意義。這實際上是您的應用程序中的主要性能損失嗎? –

+0

是的。它在不斷調用的函數中處於一個長循環中。 –

回答

0

我有使用再版更好一點結果()與Python 3.2:

>>> Timer('repr(n).encode()','n=9999').timeit() 
0.32432007789611816 
>>> Timer('("%s" % n).encode()','n=9999').timeit() 
0.44790005683898926 

但當然它並不像"%s" % n靈活。

我也已檢查的Python 3.3.0a3希望PEP393將加快轉換有點令人驚訝,但我有比3.2更壞的結果:

>>> Timer('repr(n).encode()','n=9999').timeit() 
0.35951611599921307 
>>> Timer('("%s"%n).encode()','n=9999').timeit() 
0.4658188759985933 

最後,以下:

>>> Timer('str(n).encode()','n=9999').timeit() 
0.49958825100111426 

顯示大部分成本可能來自函數調用開銷(從上面的結果中我假設整數類型的str()的Python實現在內部調用repr())。因此,如果您需要在此級別進行優化,那麼就像您所說的那樣,使用cython替換整個代碼塊可能是一條可行的路。或者更好地向我們展示您正在嘗試優化的循環,因爲可能有許多其他方法來加速它。

+0

我在問題主體中添加了一個用例。 –