Python3与Python2在列表/生成器范围性能上的比较
我有一个简单的函数,它可以把一个列表分开,并返回一个索引 i。这个索引 i 的特点是,列表中索引小于 i 的元素都比 list[i] 小,而索引大于 i 的元素都比 list[i] 大。
def partition(arr):
first_high = 0
pivot = len(arr) - 1
for i in range(len(arr)):
if arr[i] < arr[pivot]:
arr[first_high], arr[i] = arr[i], arr[first_high]
first_high = first_high + 1
arr[first_high], arr[pivot] = arr[pivot], arr[first_high]
return first_high
if __name__ == "__main__":
arr = [1, 5, 4, 6, 0, 3]
pivot = partition(arr)
print(pivot)
在 OS X 上,使用 Python 3.4 的运行时间明显比 Python 2.7.6 要长:
time python3 partition.py
real 0m0.040s
user 0m0.027s
sys 0m0.010s
time python partition.py
real 0m0.031s
user 0m0.018s
sys 0m0.011s
在 ubuntu 14.04 / 虚拟机上也是一样的情况。
使用 python3:
real 0m0.049s
user 0m0.034s
sys 0m0.015s
使用 python:
real 0m0.044s
user 0m0.022s
sys 0m0.018s
是 Python 3 本身就比 Python 2.7 慢,还是说有一些特定的优化可以让代码在 Python 2.7 上运行得更快呢?
1 个回答
13
正如评论中提到的,你应该用 timeit
来测试代码的运行时间,而不是用操作系统的工具。
我猜测在Python 3中,range
函数的速度可能稍微慢一些。在Python 2中,它直接返回一个 列表,而在Python 3中,它返回一个 range
,这个东西的行为更像是一个生成器。我做了一些性能测试,结果可能能给你一些启示:
python -mtimeit "range(10)"
1000000 loops, best of 3: 0.474 usec per loop
python3 -mtimeit "range(10)"
1000000 loops, best of 3: 0.59 usec per loop
python -mtimeit "range(100)"
1000000 loops, best of 3: 1.1 usec per loop
python3 -mtimeit "range(100)"
1000000 loops, best of 3: 0.578 usec per loop
python -mtimeit "range(1000)"
100000 loops, best of 3: 11.6 usec per loop
python3 -mtimeit "range(1000)"
1000000 loops, best of 3: 0.66 usec per loop
从结果来看,当给 range
的输入很小时,Python 2的速度比较快。如果输入变大,Python 3的 range
表现得更好。
我的建议是:用更大的数组进行测试,比如一百个或一千个元素。
实际上,我还进一步测试了对所有元素的完整迭代。结果完全支持Python 2:
python -mtimeit "for i in range(1000):pass"
10000 loops, best of 3: 31 usec per loop
python3 -mtimeit "for i in range(1000):pass"
10000 loops, best of 3: 45.3 usec per loop
python -mtimeit "for i in range(10000):pass"
1000 loops, best of 3: 330 usec per loop
python3 -mtimeit "for i in range(10000):pass"
1000 loops, best of 3: 480 usec per loop
我的结论是,遍历一个列表可能比遍历一个生成器要快。虽然后者在内存使用上绝对更高效。这是速度和内存之间权衡的经典例子。虽然速度差异本身并不那么大(少于毫秒级别)。所以你应该考虑这一点,以及哪个对你的程序更好。