在python

时间:2017-10-18 10:38:18

标签: python python-3.x performance sorting big-o

我试图说服自己,计数排序比Python中的排序方法执行得更快。然而,即使对于像1000万个元素这样的大型输入,调用已排序的内置也似乎更快。我该怎么做才能使计数排序更快?

我生成一个小写字母列表,将示例简化为26个唯一值:

letters = [random.choice(string.ascii_lowercase) for i in range(10000000)]

然后我在计算排序时做了以下变化:

def sorted_count(letters):
 counts = [0] * 26
 for letter in letters:
     counts[ord(letter) - 97] += 1
 out = [None] * len(letters)
 j = 0
 for i in range(len(counts)):
     while counts[i] > 0:
         out[j] = chr(i + 97)
         counts[i] -= 1
         j += 1
 return out

即使在10,000,000个元素上,对sorted(letters)的调用也要快4倍。 我怎样才能提高我的速度?

2 个答案:

答案 0 :(得分:3)

而不是在最后的forloop中使用while循环。 你可以简单地使用

for i in range(len(counts)):
 if counts[i]>0:
     out[j] =counts[i]*chr(i + 97)
 j+=1
return out

答案 1 :(得分:1)

这是一个修改过的函数,比建议的函数快3倍,是sorted的两倍:

import random
import string
import timeit
N = 1000000
letters = [random.choice(string.ascii_lowercase) for i in range(N)]


def original_sorted_count(letters):
    counts = [0] * 26
    for letter in letters:
        counts[ord(letter) - 97] += 1
    out = [None] * len(letters)
    j = 0
    for i in range(len(counts)):
        while counts[i] > 0:
            out[j] = chr(i + 97)
            counts[i] -= 1
            j += 1
    return out

def eric(letters):
    counts = [0] * 26
    for letter in letters:
        counts[ord(letter) - 97] += 1
    out = []
    for i in range(len(counts)):
        out += [chr(i+97)] * counts[i]
    return out

print('Original : %.3fs' %timeit.timeit(lambda: original_sorted_count(letters), number=20))
print('Sorted   : %.3fs' %timeit.timeit(lambda: sorted(letters), number=20))
print('Eric     : %.3fs' %timeit.timeit(lambda: eric(letters), number=20))

print(eric(letters) == sorted(letters))

输出:

Original : 9.616s
Sorted   : 6.367s
Eric     : 3.604s
True