2017-07-11 40 views
7

列表使用無因的算法我想實現利用指數1..n因爲它是非常容易出錯的一個各項指標轉變,我決定讓智能和插入啞元每個列表的開始,所以我可以使用紙上的原始公式。PyPy:嚴重的性能下降時,與整數

對於急促的緣故,認爲這個玩具例子:

def calc(N): 
    nums=[0]+range(1,N+1) 
    return sum(nums[1:]) #skip first element 

不過,我開始擔心了,我的成績是虛假的,因爲我意外的地方訪問第0個元素,不知道的。所以我更聰明和使用None代替0作爲第一要素 - 將導致運行時錯誤與它的每一個算術運算:

def calc_safe(N): 
    nums=[None]+range(1,N+1) #here we use "None" 
    return sum(nums[1:]) 

出人意料的是,這個小變化導致了巨大的性能損失pypy(甚至與目前的5.8版本) - 代碼變得慢10倍左右!這裏是我的機器上的時間:

    pypy-5.8 cpython 
calc(10**8)   0.5 sec  5.5 sec 
calc_safe(10**8) 7.5 sec  5.5 sec 

作爲一個邊節點:CPython的不關心,None是否使用與否。

所以我的問題是雙重的:

  1. 顯然使用None是不是一個好主意,但是爲什麼呢?
  2. 是否有可能獲得None的安全方法並保持性能?

編輯:由於阿明解釋,並非所有的名單都是平等的,我們可以看到,它的策略是通過使用:

import __pypy__ 
print __pypy__.strategy(nums) 

在第一種情況下,它是IntegerListStrategy和第二ObjectListStrategy。如果我們用一個大的整數值(如2**100)同樣會發生,而不是None

回答

4

對於僅包含整數的列表,PyPy已經有了一個特例 - 它將它們存儲爲array.array。如果其中有一個None,那麼這個優化不再起作用。

這也許可以固定內PyPy允許無作爲特殊情況......

+0

這在某種程度上可以看到明確的,無論是優化或使用該名單的非優化的版本? – ead

+0

是的,''__pypy __。策略(LST)''。 –