Почему Python 3.1 медленнее, чем 2.6 для этого кода? - PullRequest
5 голосов
/ 11 июля 2010

Рассмотрим следующий код (из здесь , с увеличением количества тестов):

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.73663210869
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

Кто-нибудь знает, почему этот код выполняется в Python 3.1 в три раза медленнее?1014 *

Ответы [ 2 ]

3 голосов
/ 11 июля 2010

У меня стабильно уменьшаются времена с 2.5, 2.6, 2.7 и 3.1 (Windows XP SP2) ... с версией "/".При использовании // 3,1 раза были значительно меньше, чем в 2 раза, например, «Норма» снизилась с 6,35 (py2,7) до 3,62 (py3.1).есть целые числа (машинное слово, 32 или 64 бита) и длинные (переменная длина).В 3.x long был переименован в int, и int ушёл.Я предполагаю, что преобразование из long в float может вызвать дополнительное время с /.

В любом случае, гораздо лучшая версия «Alt» будет начинаться с этого кода:

2 голосов
/ 11 июля 2010

Оператор // выполняет целочисленное деление (или деление по полу) как в Python 2, так и в 3, тогда как оператор / выполняет деление по полу в Python 2 с заданными целочисленными операндами и истинное деление в Python 3 при любых операндах.

Попробуйте заменить оператор / на оператор //.

...