简体   繁体   English

Python3与Python2列表/生成器范围性能

[英]Python3 vs Python2 list/generator range performance

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. 我有这个简单的函数,它分区列表并返回列表中的索引i,使索引小于i的元素小于list [i],索引大于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)

The runtime is substantially bigger with python 3.4 that python 2.7.6 on OS X: OS X上的python 2.7.6的python 3.4运行时间要大得多:

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

Same thing on ubuntu 14.04 / virtual box 在ubuntu 14.04 /虚拟机上也是如此

python3: python3:

real 0m0.049s
user 0m0.034s
sys  0m0.015s

python: 蟒蛇:

real 0m0.044s
user 0m0.022s
sys  0m0.018s

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 python3本身是否比python2.7慢,或者是否对代码进行了任何特定的优化,使得运行速度与python2.7一样快

As mentioned in the comments, you should be benchmarking with timeit rather than with OS tools. 正如评论中所提到的,您应该使用timeit而不是使用OS工具进行基准测试。

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. 我的猜测是该range的功能可能是在Python 3.在Python 2执行慢一点它只是返回一个列表 ,在Python 3它返回一个range ,它们的行为或多或少就像一台发电机。 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

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. 正如您所看到的,当提供给range输入很小时 ,它在Python 2中往往很快。如果输入增长,那么Python 3的range表现得更好。

My suggestion: test the code for larger arrays, with a hundred or a thousand elements. 我的建议:测试更大数组的代码,有一百或一千个元素。

Actually, I went further and test a complete iteration through the elements. 实际上,我进一步测试了元素的完整迭代。 The results were totally in favor of Python 2: 结果完全支持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. 因此,您应该重视这一点,并为您的计划做些什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM