2010-07-11 69 views
5

考慮下面的代碼(從here,與試驗次數增加):爲什麼Python 3.1的代碼比2.6慢?

from timeit import Timer 

def find_invpow(x,n): 
    """Finds the integer component of the n'th root of x, 
    an integer such that y ** n <= x < (y + 1) ** n. 
    """ 
    high = 1 
    while high ** n < x: 
     high *= 2 
    low = high/2 
    while low < high: 
     mid = (low + high) // 2 
     if low < mid and mid**n < x: 
      low = mid 
     elif high > mid and mid**n > x: 
      high = mid 
     else: 
      return mid 
    return mid + 1 

def find_invpowAlt(x,n): 
    """Finds the integer component of the n'th root of x, 
    an integer such that y ** n <= x < (y + 1) ** n. 
    """ 
    low = 10 ** (len(str(x))/n) 
    high = low * 10 
    while low < high: 
     mid = (low + high) // 2 
     if low < mid and mid**n < x: 
      low = mid 
     elif high > mid and mid**n > x: 
      high = mid 
     else: 
      return mid 
    return mid + 1 

x = 237734537465873465 
n = 5 
tests = 1000000 

print "Norm", Timer('find_invpow(x,n)', 'from __main__ import find_invpow, x,n').timeit(number=tests) 
print "Alt", Timer('find_invpowAlt(x,n)', 'from __main__ import find_invpowAlt, x,n').timeit(number=tests) 

使用Python 2.6(Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) [GCC 4.4.3] on linux2),報告的時間是:

Norm 9.869 
Alt 9.53973197937 

然而,在相同的機器上使用Python 3.1(Python 3.1.2 (r312:79147, Apr 15 2010, 15:35:48) [GCC 4.4.3] on linux2),時間是:

Norm 28.4206559658 
Alt 26.8007400036 

有沒有人知道爲什麼這個鱈魚e在Python 3.1上運行速度慢三倍?

+1

沒有攝製:python3.1比2.6快了30%左右我的機器上。 – SilentGhost 2010-07-11 09:45:08

+0

謝謝。你在運行什麼操作系統?我在Ubuntu 10.04 64位上獲得了上述時間。 – user200783 2010-07-11 09:47:08

+0

同一個系統的32位版本 – SilentGhost 2010-07-11 09:49:55

回答

3

我從2.5,2.6,2.7和3.1(Windows XP SP2)以「/」版本穩步下降。用//,3.1倍顯着小於2.X倍,例如「標準」從6.35(py2.7)下降到3.62(py3.1)。請注意,在2.x中,有ints(機器字,32或64位)和longs(可變長度)。在3.x中,long已經被重命名爲int,並且int消失了。我的猜測是,從長轉換爲浮動可能會導致額外的時間/。

在任何情況下,一個更好的「Alt」鍵的版本將與此代碼開始:

high = 1 
highpown = 1 
while highpown < x: 
    high <<= 1 
    highpown <<= n 
+0

「將從此代碼開始......」。緊隨着'low = high // 2'? – user200783 2010-07-11 11:38:25

+0

@保羅貝克:當然。在這兩個函數中'low = high/2'是一個BUG。 – 2010-07-11 11:56:41

+1

+1。我強烈懷疑這是'int'與'long'之間的差異。請注意,在32位機器上,被測試的值不適合int,因此您將在Python 2.x和3.x中使用long來進行計算。但是在64位機器上,你在2.x中使用'int'算術,在3.x中使用任意精度算術。 – 2010-07-11 14:00:55

2

//運算符在python 2和python 3中執行整數除法(或floor division),而/運算符在給定任何操作數的情況下在python 2中給出整數操作數和真除數。

嘗試用//運營商替換/運營商。

+0

謝謝。我用'low = high // 2'和'low = 10 **(len(str(x))/ n)'用'low = 10 **(len(str(x ))// n)'。這使得來自__future__進口部門的2.6的表現符合2.6的正常表現。不幸的是,3.1的性能沒有變化 - 仍然比2.6慢3倍。 – user200783 2010-07-11 10:42:50

+0

當然,問題在於python3中的「整數」是python2的老「長」。操作員在這裏沒有關係:) – 2015-02-19 16:01:57