用Python排序的最快方法

时间:2010-10-04 13:12:31

标签: python arrays performance sorting

在Python中对大于0且小于100000的整数数组进行排序的最快方法是什么?但不使用像sort这样的内置函数。

我正在考虑根据输入大小组合2种运动功能的可能性。

9 个答案:

答案 0 :(得分:15)

如果您对渐近时间感兴趣,那么计算排序或基数排序可以提供良好的性能。

但是,如果您对挂钟时间感兴趣,则需要使用您的特定数据集来比较不同算法之间的性能,因为不同的算法对不同的数据集执行不同的操作。在这种情况下,它总是值得尝试快速排序:

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

答案 1 :(得分:7)

由于你知道数字的范围,你可以使用Counting Sort,它将是及时的线性。

答案 2 :(得分:3)

理论上,基数排序在线性时间内运行(排序时间大致与数组大小成正比),但实际上Quicksort可能更适合,除非你对绝对大规模的数组进行排序。

如果你想快速进行快速排序,可以在数组大小变小时使用插入排序。

理解算法复杂性和Big-O表示法的概念可能会有所帮助。

答案 3 :(得分:2)

早期版本的Python使用samplesort(具有大样本大小的快速排序的变体)和二进制插入排序的混合作为内置排序算法。事实证明这有点不稳定。 S0,从python 2.3开始使用adaptive mergesort算法。

mergesort顺序(平均值)= O(nlogn)。 mergesort的顺序(最差)= O(nlogn)。 但是快速排序(最差)= n * 2

如果您使用list=[ .............. ]

list.sort()使用mergesort algorithm.

为了比较排序算法,您可以阅读wiki

详细比较comp

答案 4 :(得分:1)

我们可以使用字典来计算排序,以最大限度地减少额外的空间使用量,同时保持较低的运行时间。由于python与C的实现开销,对于小尺寸的输入数组,count排序要慢得多。当数组大小(COUNT)约为100万时,计数排序开始超过常规排序。

如果你真的想要小尺寸输入的大幅加速,请在C中实现计数排序并从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

答案 5 :(得分:1)

我可能会稍微迟到一下,但是有一篇有趣的文章可以比较https://www.linkedin.com/pulse/sorting-efficiently-python-lakshmi-prakash

的不同种类。

主要的一点是,虽然默认排序很好,但我们可以使用quicksort的编译版本做得更好。这需要Numba包。

enter image description here

这里是Github回购的链接: https://github.com/lprakash/Sorting-Algorithms/blob/master/sorts.ipynb

答案 6 :(得分:0)

内置函数是最好的,但由于你不能使用它们看看:

http://en.wikipedia.org/wiki/Quicksort

答案 7 :(得分:0)

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

这是我创建的算法,但速度非常快。只做排序(l) l是您要排序的列表。

答案 8 :(得分:0)

@fmark 我对http://rosettacode.org/wiki/Sorting_algorithms/Quicksort#Python的python quicksorts写的python merge-sort实现的一些基准测试 并从最佳答案。

  1. 列表的大小和列表中不相关的数字大小
  2. 合并排序获胜,但它使用内置的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))