为什么Python 3.1比这个代码慢2.6?

use*_*783 5 python performance python-3.x

考虑以下代码(从这里开始,测试数量增加):

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)
Run Code Online (Sandbox Code Playgroud)

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

Norm 9.73663210869
Alt 9.53973197937
Run Code Online (Sandbox Code Playgroud)

但是,在使用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
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么这个代码在Python 3.1上运行速度慢三倍?

Joh*_*hin 3

使用“/”版本时,我的时间从 2.5、2.6、2.7 和 3.1 (Windows XP SP2) 开始稳步减少。使用 // 时,3.1 倍明显小于 2.X 倍,例如“Norm”从 6.35 (py2.7) 下降到 3.62 (py3.1)。

请注意,在 2.x 中,有 int(机器字,32 或 64 位)和 long(可变长度)。在 3.x 中,long 已更名为 int,并且 int 消失了。我的猜测是,从 long 转换为 float 可能会导致 / 花费额外的时间。

无论如何,更好的“Alt”版本将从以下代码开始:

high = 1
highpown = 1
while highpown < x:
    high <<= 1
    highpown <<= n
Run Code Online (Sandbox Code Playgroud)