特定の状況で組み込みの timsort を打ち負かすために、python でカウントソートを記述しようとしています。現在、組み込みの sorted 関数よりも優れていますが、非常に大きな配列 (長さが 100 万以上の整数、1000 万以上は試していません) および 10,000 を超えない範囲に対してのみです。さらに、勝利は狭く、特にそれに合わせて調整されたランダムリストでは、カウントソートはかなりの差でしか勝てません.
Pythonコードをベクトル化することで得られる驚異的なパフォーマンスの向上について読んだことがありますが、その方法やここでの使用方法については特に理解していません。このコードをベクトル化して高速化する方法を知りたいです。その他のパフォーマンスに関する提案は大歓迎です。
Python と stdlibs のみの現在の最速バージョン:
from itertools import chain, repeat
def untimed_countsort(unsorted_list):
counts = {}
for num in unsorted_list:
try:
counts[num] += 1
except KeyError:
counts[num] = 1
sorted_list = list(
chain.from_iterable(
repeat(num, counts[num])
for num in xrange(min(counts), max(counts) + 1)))
return sorted_list
ここで重要なのは生の速度だけなので、速度を上げるためにさらに多くのスペースを犠牲にすることは完全に公正なゲームです.
コードはすでにかなり短く明確であることを認識しているため、速度を改善する余地がどれだけあるかはわかりません。
誰かがコードを短くするためにコードを変更した場合、遅くならない限り、それも素晴らしいことです。
実行時間はほぼ 80% 短縮されました! 現在のテストでは、Timsort の 3 倍の速度になりました。
ロングショットでこれを行う絶対最速の方法は、numpy でこのワンライナーを使用することです。
def np_sort(unsorted_np_array):
return numpy.repeat(numpy.arange(1+unsorted_np_array.max()), numpy.bincount(unsorted_np_array))
これは、純粋な python バージョンよりも約 10 ~ 15 倍速く、Timsort よりも約 40 倍速く実行されます。numpy 配列を受け取り、numpy 配列を出力します。