2015-11-06 43 views
0

我試圖優化我的Python 2.7.x代碼。我將在for循環中執行一個操作,可能需要數百萬次,所以我希望它儘可能快。轉換字符串列表整數和Python代碼優化漂浮

我的操作是獲取10個字符串的列表並將它們轉換爲2個整數,然後將其轉換爲8個浮點數。

這是我嘗試的MWE:

import timeit 

    words = ["1"] * 10 

    start_time = timeit.default_timer() 
    for ii in range(1000000): 
     values = map(float, words) 
     values[0] = int(values[0]) 
     values[1] = int(values[1]) 
    print "1", timeit.default_timer() - start_time 

    start_time = timeit.default_timer() 
    for ii in range(1000000): 
     values = map(int, words[:2]) + map(float, words[2:]) 
    print "2", timeit.default_timer() - start_time 

    start_time = timeit.default_timer() 
    local_map = map 
    for ii in range(1000000): 
     values = local_map(float, words) 
     values[0] = int(values[0]) 
     values[1] = int(values[1]) 
    print "3", timeit.default_timer() - start_time 

    1 2.86574220657 
    2 3.83825802803 
    3 2.86320781708 

的一個代碼塊是我管理的最快的。 map函數似乎比使用列表理解更快。但是仍然有一些冗餘,因爲我將所有內容映射到一個浮點數,然後將前兩個項目更改爲整數。

有沒有比我的代碼更快的東西?

爲什麼不讓地圖功能本地化,local_map = map,提高第三塊代碼的速度?

+0

在一般說明中,使用'%timeit'可能更適合性能測量... – Julien

+0

您是否受限於Python 2? – Felk

+0

@Felk沒錯的Python 2.7.x – innisfree

回答

0

我還沒有找到更快的東西,但是在某些情況下,您最快的代碼實際上會出錯。問題是,對於超出2 ** 53(IIRC;可能在位數上偏離1)的值,Python float(它是C double)的精度有限,但它不能表示所有整數值。相比之下,Python int是任意的精度;如果你有記憶,它可以有效地代表無限的價值。

你會想改變:

values[0] = int(values[0]) 
values[1] = int(values[1]) 

到:

values[0] = int(words[0]) 
values[1] = int(words[1]) 

,以避免這種情況。重新分析會使這更依賴於被解析字符串的長度(因爲對於更長的輸入,多次轉換花費更多)。

至少在我的Python(3.5)工作得相當快的另一種方法是預構建一組轉換器,以便您可以直接調用正確的函數。例如:

words = ["1"] * 10 
converters = (int,) * 2 + (float,) * 8 

values = [f(v) for f, v in zip(converters, words)] 

你想的zip兩個版本的測試,看看是否基於itertools.izip發電機的發電list版本速度更快(簡稱輸入,比如這些,我真的不能說)。在Python 3.5(其中zip始終是Py2的itertools.izip這樣的生成器)時,這比相同輸入的最快解決方案長10%左右(我使用min()timeit.repeat運行,而不是您使用的手動滾動版本)。如果投入較大(因此解析兩次會更加昂貴),它可能會更好。

相關問題