2012-07-18 89 views
7

这是我跑的代码:为什么是Python的 “排序()” 比慢 “副本,那么的.sort()”

import timeit 

print timeit.Timer('''a = sorted(x)''', '''x = [(2, 'bla'), (4, 'boo'), (3, 4), (1, 2) , (0, 1), (4, 3), (2, 1) , (0, 0)]''').timeit(number = 1000) 
print timeit.Timer('''a=x[:];a.sort()''', '''x = [(2, 'bla'), (4, 'boo'), (3, 4), (1, 2) , (0, 1), (4, 3), (2, 1) , (0, 0)]''').timeit(number = 1000) 

和这里的结果:

0.00259663215837 
0.00207390190177 

我想知道为什么使用.sort()始终比sorted()快,即使它们都是复制列表?

注:我上的2.53GHz的酷睿i5运行的Python 2.7使用Win7的

+0

推荐你试试这个连续多次与更大的名单严谨 – 2012-07-18 18:08:08

+0

@AndrewGorcester我买了更大的列表建议,但为什么更多次?对于合理的统计准确度,1000是不够的? – robert 2012-07-18 18:09:26

+0

对不起,我不熟悉timeit模块,刚刚意识到它在您回答的同时重复了1000次。这应该是很多重复。 – 2012-07-18 18:10:30

回答

8

你正在寻找不同的是微不足道的,完全消失了较长的列表。简单地增加* 1000x定义给出了我的机器上,结果如下:

2.74775004387 
2.7489669323 

我最好的,理由是sorted()是稍慢你是sorted()需要使用一些通用的代码,可以任意复制猜测可迭代到列表中,而直接复制列表可以假设源也是列表。 CPython使用的排序代码实际上与list.sort()sorted()相同,所以这不是导致差异的原因。

编辑:本source code of the current development version of sorted()做的

a = list(x) 
a.sort() 

乃至道德等同,使用此代码,而不是你的第二个版本,消除了任何列表大小的任何显著的速度差异。

+0

[我的机器上的结果支持您的答案](http://stackoverflow.com/a/11547854/4279)。 – jfs 2012-07-18 18:21:22

+2

Yup - 'list.sort'可以使用已知的大小,并且交换大小为'sorted()'的元素必须使用未知大小和泛型迭代器,因此可能必须在构建时分配内存(可能强制一个memcpy,如果不是contig。),但是这应该是最小的,正如你所说的那样。复制列表非常简单,因为这只是一个简单的malloc/memcpy操作(并创建一个新的PyObject *) – 2012-07-18 18:26:35

1

为了支持@Sven Marnach's answer

没有为小名单小的差异:

$ python2.7 -mtimeit -s "x = [(2, 'bla'), (4, 'boo'), (3, 4), (1, 2) , (0, 1), (4, 3), (2, 1) , (0, 0)]; s=sorted" "a=s(x)" 
1000000 loops, best of 3: 1.87 usec per loop 

$ python2.7 -mtimeit -s "x = [(2, 'bla'), (4, 'boo'), (3, 4), (1, 2) , (0, 1), (4, 3), (2, 1) , (0, 0)]" "a=x[:];a.sort()" 
1000000 loops, best of 3: 1.66 usec per loop 

的差异与* 1000(大名单)消失:

$ python2.7 -mtimeit -s "x = [(2, 'bla'), (4, 'boo'), (3, 4), (1, 2) , (0, 1), (4, 3), (2, 1) , (0, 0)]*1000; s=sorted" "a=s(x)" 
100 loops, best of 3: 3.42 msec per loop 

$ python2.7 -mtimeit -s "x = [(2, 'bla'), (4, 'boo'), (3, 4), (1, 2) , (0, 1), (4, 3), (2, 1) , (0, 0)]*1000" "a=x[:];a.sort()" 
100 loops, best of 3: 3.48 msec per loop 
相关问题