为何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.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上运行速度慢了三倍?
2 个回答
2
//
这个符号在Python 2和Python 3中都用来进行整数除法(也叫向下取整除法),而/
这个符号在Python 2中对整数进行除法时也是向下取整,但在Python 3中无论是什么数字都进行真实除法。
试着把/
换成//
吧。
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版本中,有两种数字类型:ints(机器字长,32位或64位)和longs(可变长度)。而在3.x版本中,long被重新命名为int,原来的int类型消失了。我猜测,从long转换为float可能会导致使用“/”时的额外时间。
无论如何,一个更好的“替代”版本可以从这段代码开始:
high = 1
highpown = 1
while highpown < x:
high <<= 1
highpown <<= n