为什么Python';s";排序();慢于;然后复制.sort();
以下是我运行的代码:为什么Python';s";排序();慢于;然后复制.sort();,python,performance,sorting,optimization,Python,Performance,Sorting,Optimization,以下是我运行的代码: 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
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()快,即使两者都是复制列表?
注意:我使用Win7在2.53Ghz i5上运行Python2.7,您看到的差别很小,对于较长的列表来说完全消失了。只需将
*1000
添加到x
的定义中,即可在我的机器上获得以下结果:
2.74775004387
2.7489669323
对于sorted()
对您来说稍微慢一点的原因,我的最佳猜测是sorted()
需要使用一些通用代码,可以将任何iterable复制到列表中,而直接复制列表可以假设源也是一个列表。CPython使用的排序代码实际上与list.sort()
和sorted()
相同,因此这不是造成差异的原因
编辑:道德等同于
a = list(x)
a.sort()
事实上,使用此代码而不是第二个版本可以消除任何列表大小的速度差异。支持:
小列表有一点不同:
$ 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
(较大的列表):
建议您连续多次尝试此功能,并列出更大的rigor@AndrewGorcester我买了更大的清单建议,但为什么更多次?对于合理的统计准确性来说,1000还不够吗?对不起,我不熟悉timeit模块,刚刚意识到它在您回复的同时被重复了1000次。这应该是大量的重复。是的-
列表。sort
可以使用已知的大小,并交换该大小内的元素,sorted()
必须使用未知的大小和通用的iterables,因此可能必须在构建时分配内存(如果不是contig,可能会强制使用memcpy),但这应该是最小的。复制列表相当简单,因为这只是一个简单的malloc/memcpy操作(以及创建一个新的PyObject*)
$ 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