我试图说服自己,计数排序比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倍。
我怎样才能提高我的速度?
答案 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