2012-07-18 47 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 
相關問題