考虑以下代码(来自here,测试次数增加):
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上运行速度慢三倍?
答案 0 :(得分: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中,有整数(机器字,32或64位)和长整数(可变长度)。在3.x中,long已重命名为int,并且int消失了。我的猜测是,从long转换为float可能会导致额外的时间使用/.
无论如何,更好的“Alt”版本将从这段代码开始:
high = 1
highpown = 1
while highpown < x:
high <<= 1
highpown <<= n
答案 1 :(得分:2)
//
运算符在python 2和3中执行整数除法(或舍入除法),而/
运算符在python 2中执行floor division,给定整数操作数,并在python 3中执行true division操作数。
尝试使用/
运算符替换//
运算符。