问题描述
我有一个简单的函数,可以对列表进行分区并返回列表中的索引i,这样索引i小于i的元素要比list [i]小,索引大于i的元素要大.
I have this simple function that partitions a list and returns an index i in the list such that elements at indices less that i are smaller than list[i] and elements at indices greater than i are bigger.
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)
使用python 3.4的运行时要比python 2.7.6的运行时大得多在OS X上:
The runtime is substantially bigger with python 3.4 that python 2.7.6on OS X:
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/虚拟盒上的内容相同
Same thing on ubuntu 14.04 / virtual box
python3:
real 0m0.049s
user 0m0.034s
sys 0m0.015s
python:
real 0m0.044s
user 0m0.022s
sys 0m0.018s
python3本质上比python2.7慢吗?还是对代码进行了任何特定的优化,使其运行速度与在python2.7上一样快
Is python3 inherently slower that python2.7 or is there any specific optimizations to the code do make run as fast as on python2.7
推荐答案
如注释中所述,您应该使用timeit
进行基准测试,而不是使用OS工具.
As mentioned in the comments, you should be benchmarking with timeit
rather than with OS tools.
我的猜测是range
函数在Python 3中的执行速度可能会慢一些.在Python 2中,它只是返回,在Python 3中返回 range
一个或多或少像发电机的行为.我做了一些基准测试,这就是结果,这可能暗示了您正在经历的事情:
My guess is the range
function is probably performing a little slower in Python 3. In Python 2 it simply returns a list, in Python 3 it returns a range
which behave more or less like a generator. I did some benchmarking and this was the result, which may be a hint on what you're experiencing:
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
的输入为 small 时,在Python 2中它往往很快.如果输入增加,则Python 3的range
表现会更好.
As you can see, when input provided to range
is small, it tends to be fast in Python 2. If the input grows, then Python 3's range
behave better.
我的建议:测试包含一百或一千个元素的较大数组的代码.
My suggestion: test the code for larger arrays, with a hundred or a thousand elements.
实际上,我走得更远,并测试了元素的完整迭代.结果完全支持Python 2:
Actually, I went further and test a complete iteration through the elements. The results were totally in favor of 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
我的结论是,迭代列表可能比通过生成器迭代更快.尽管后者绝对在内存消耗方面更为有效.这是在速度和内存之间进行权衡的经典示例.尽管速度差异本身并没有那么大(小于毫秒).因此,您应该重视这一点,并且对您的程序更有利.
My conclusion is that, is probably faster to iterate through a list than through a generator. Although the latter is definitely more efficient regarding memory consumption. This is a classic example of the trade off between speed and memory. Although the speed difference is not that big per se (less than miliseconds). So you should value this and what's better for your program.
这篇关于Python3 vs Python2列表/生成器范围性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!