[英]Fastest way to sort in Python
在 Python 中對大於 0 且小於 100000 的整數數組進行排序的最快方法是什么? 但不使用像 sort 這樣的內置函數。
我正在考慮根據輸入大小組合 2 項運動功能的可能性。
如果您對漸近時間感興趣,則對sort或radix排序進行計數可以提供良好的性能。
但是,如果您對掛鍾時間感興趣,則需要使用特定數據集比較不同算法之間的性能,因為不同算法對不同數據集的執行方式會有所不同。 在這種情況下,總是值得嘗試快速排序:
def qsort(inlist):
if inlist == []:
return []
else:
pivot = inlist[0]
lesser = qsort([x for x in inlist[1:] if x < pivot])
greater = qsort([x for x in inlist[1:] if x >= pivot])
return lesser + [pivot] + greater
來源: http : //rosettacode.org/wiki/Sorting_algorithms/Quicksort#Python
由於您知道數字的范圍,因此可以使用“ 計數排序” ,它在時間上是線性的。
Radix排序理論上以線性時間運行(排序時間大致與數組大小成正比增長),但是實際上,除非您要對大量數組進行排序,否則Quicksort可能更適合。
如果要使快速排序更快一些,可以在數組大小變小時使用插入排序]。
理解算法復雜性和Big-O表示法的概念也可能會有所幫助。
我們可以使用字典來進行計數排序,以最大程度地減少額外的空間使用,並保持較低的運行時間。 對於小尺寸的輸入數組,由於python vs C的實現開銷,計數排序要慢得多。 當數組(COUNT)的大小約為100萬時,計數排序開始超過常規排序。
如果您真的想為較小的輸入提供巨大的加速,請在C中實現count排序,然后從Python調用它。
(修復了Aaron(+1)幫助捕獲的錯誤...)下面的僅python實現比較了兩種方法...
import random
import time
COUNT = 3000000
array = [random.randint(1,100000) for i in range(COUNT)]
random.shuffle(array)
array1 = array[:]
start = time.time()
array1.sort()
end = time.time()
time1 = (end-start)
print 'Time to sort = ', time1*1000, 'ms'
array2 = array[:]
start = time.time()
ardict = {}
for a in array2:
try:
ardict[a] += 1
except:
ardict[a] = 1
indx = 0
for a in sorted(ardict.keys()):
b = ardict[a]
array2[indx:indx+b] = [a for i in xrange(b)]
indx += b
end = time.time()
time2 = (end-start)
print 'Time to count sort = ', time2*1000, 'ms'
print 'Ratio =', time2/time1
我可能會晚一點,但是有一篇有趣的文章比較了https://www.linkedin.com/pulse/sorting-ficiently-python-lakshmi-prakash
主要優點之一是,盡管默認排序效果很好,但我們可以使用Quicksort的編譯版本做得更好。 這需要Numba程序包。
這是Github存儲庫的鏈接: https : //github.com/lprakash/Sorting-Algorithms/blob/master/sorts.ipynb
def sort(l):
p = 0
while(p<len(l)-1):
if(l[p]>l[p+1]):
l[p],l[p+1] = l[p+1],l[p]
if(not(p==0)):
p = p-1
else:
p += 1
return l
這是我創建的算法,但是速度很快。 只需將sort(l)作為您要排序的列表即可。
內置函數是最好的,但是由於您無法使用它們,因此請查看以下內容:
@fmark我針對來自http://rosettacode.org/wiki/Sorting_algorithms/Quicksort#Python和最高答案的python quicksorts編寫的python merge-sort實現的一些基准測試。
合並排序獲勝,但是它使用內置int()
import numpy as np
x = list(np.random.rand(100))
# TEST 1, merge_sort
def merge(l, p, q, r):
n1 = q - p + 1
n2 = r - q
left = l[p : p + n1]
right = l[q + 1 : q + 1 + n2]
i = 0
j = 0
k = p
while k < r + 1:
if i == n1:
l[k] = right[j]
j += 1
elif j == n2:
l[k] = left[i]
i += 1
elif left[i] <= right[j]:
l[k] = left[i]
i += 1
else:
l[k] = right[j]
j += 1
k += 1
def _merge_sort(l, p, r):
if p < r:
q = int((p + r)/2)
_merge_sort(l, p, q)
_merge_sort(l, q+1, r)
merge(l, p, q, r)
def merge_sort(l):
_merge_sort(l, 0, len(l)-1)
# TEST 2
def quicksort(array):
_quicksort(array, 0, len(array) - 1)
def _quicksort(array, start, stop):
if stop - start > 0:
pivot, left, right = array[start], start, stop
while left <= right:
while array[left] < pivot:
left += 1
while array[right] > pivot:
right -= 1
if left <= right:
array[left], array[right] = array[right], array[left]
left += 1
right -= 1
_quicksort(array, start, right)
_quicksort(array, left, stop)
# TEST 3
def qsort(inlist):
if inlist == []:
return []
else:
pivot = inlist[0]
lesser = qsort([x for x in inlist[1:] if x < pivot])
greater = qsort([x for x in inlist[1:] if x >= pivot])
return lesser + [pivot] + greater
def test1():
merge_sort(x)
def test2():
quicksort(x)
def test3():
qsort(x)
if __name__ == '__main__':
import timeit
print('merge_sort:', timeit.timeit("test1()", setup="from __main__ import test1, x;", number=10000))
print('quicksort:', timeit.timeit("test2()", setup="from __main__ import test2, x;", number=10000))
print('qsort:', timeit.timeit("test3()", setup="from __main__ import test3, x;", number=10000))
桶大小為 1 的桶排序。內存為 O(m),其中 m = 被排序的值的范圍。 運行時間為 O(n),其中 n = 排序的項目數。 當用於記錄計數的整數類型有界時,如果任何值出現超過 MAXINT 次,則此方法將失敗。
def sort(items):
seen = [0] * 100000
for item in items:
seen[item] += 1
index = 0
for value, count in enumerate(seen):
for _ in range(count):
items[index] = value
index += 1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.