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

时间:2014-05-01 15:30:36

标签: python performance python-2.7 python-3.x generator

我有这个简单的函数,它对列表进行分区并在列表中返回索引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)

python 2.7.6的python 3.4运行时间要大得多 在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 / virtual box

上也是如此

python3:

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

蟒:

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

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

1 个答案:

答案 0 :(得分:13)

正如评论中所提到的,您应该使用timeit而不是使用操作系统工具进行基准测试。

我的猜测是range函数可能在Python 3中运行得慢一点。在Python 2中它只返回一个list,在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的输入是 small 时,它在Python 2中往往很快。如果输入增长,那么Python 3&#39; s {{ 1}}表现得更好。

我的建议:测试更大数组的代码,包含一百或一千个元素。

实际上,我进一步测试了元素的完整迭代。结果完全支持Python 2:

range

我的结论是,迭代列表可能比通过生成器更快。虽然后者在内存消耗方面肯定更有效。这是速度和记忆之间权衡的典型例子。虽然速度差不是那么大本身(小于几毫秒)。因此,您应该重视这一点以及对您的计划有什么好处。