sortプログラムの速度比較 1
概要
ソートするプログラムやAPIは多数あります.
ソート時間を比較しました.
予想通りLinuxのsortプログラムが最速でした.
比較対象
・Linuxのsortコマンド(LC_ALL=空白 と LC_ALL=C)
・Rubyの Array.sort() と Array.sort!()
・Pythonの Array.sort() と sorted()関数
・(参考)Linuxのcatプログラム
結果
凡例とプログラム, APIの対応.詳細は後述
両対数グラフです.各線の左端より左は計測値が0になってしまい,対数グラフに表示できませんでした.
catは,データファイルを読み込んでソートせずにそのまま出力するプログラムです.入出力の時間が測れます.
他のソートプログラムの所要時間は,catの所要時間より圧倒的に長いので,ソートプログラムの消費時間の多くがソートに要した時間と予想します.
解説
Linuxのsortプログラムはマージソートを使っています.
マージソートはo(n * log(n))です.
sort プログラムは,すべてのコア(8コア)を用いてソートしています.
RubyやPythonのプログラムは1コアしか使っていません.
入力データをテキストデータとしてソートせずに,int型に変換してからソートするとRubyやPythonは速くなります.
コメント
sortコマンド(LC_ALL=)とPythonがほぼ同じ性能になる理由が分からないです.詳しい方,教えてください...
sort(LC_ALL=C)に関して,プロセス優先度を上げる(nice -20),sortを-O3オプションを付けて自分でコンパイルしたものを使う,などをやってみましたがこれ以上速くはなりませんでした.
測定条件
ソートデータ
以下の様なテキストファイル.
各行に10桁の10進数が1個書いてある.31bit乱数.
1804289383
0846930886
1681692777
1714636915
1957747793
(以下略)
テキストデータは以下のプログラムで作成
#include <stdio.h>
void main(int argc, char **argv){
int i,max=100;
if( 1<argc ){
max = atoi(argv[1]);
}
for(i=0; i<max; i++){
printf("%010d\n", rand());
}
}
ソート方法
各行をテキストデータとしてソート.
入力はファイルからの読み込みで行い,出力は /dev/null へリダイレクトしている.
所要時間は /usr/bin/time コマンドで計測.
ソートデータを作成してすぐに読み込んでソートを実行.よって,データはpageキャッシュから読み込んでいると思います.
プログラム
python0
with open('a.txt') as f:
lines = f.readlines()
lines.sort()
print(lines)
python1
with open('a.txt') as f:
lines = f.readlines()
print(sorted(lines))
ruby0
a = open("a.txt")
lines = a.readlines
print lines.sort
ruby1
a = open("a.txt")
lines = a.readlines
print lines.sort!
ベンチマークシェルスクリプト
python0の例
gcc a.c
for((n=1; n<=30000000; n*=2))
do
echo ${n}
./a.out ${n} > a.txt
rm -f result.${n}.txt
for i in {0..10}
do
echo ${n}.${i}
/usr/bin/time python3 sort.py > /dev/null 2>> result.${n}.txt
done
done
python1 は 全く同一
ruby0 と ruby1は,10行目が以下の様に変わる.
10c10
< /usr/bin/time python3 sort.py > /dev/null 2>> result.${n}.txt
---
> /usr/bin/time ruby sort.rb > /dev/null 2>> result.${n}.txt
sortcommand0 は,10行目が以下の様に変わる.
10c10
< /usr/bin/time python3 sort.py > /dev/null 2>> result.${n}.txt
---
> export LC_ALL= ; /usr/bin/time sort a.txt > /dev/null 2>> result.${n}.txt
sortcommand1 は,10行目が以下の様に変わる.
(厳密には,2行目の繰り返し回数も変えている)
10c10
< /usr/bin/time python3 sort.py > /dev/null 2>> result.${n}.txt
---
> export LC_ALL=C ; /usr/bin/time sort a.txt > /dev/null 2>> result.${n}.txt
cat は,10行目が以下の様に変わる.
10c10
< /usr/bin/time python3 sort.py > /dev/null 2>> result.${n}.txt
---
> /usr/bin/time cat a.txt > /dev/null 2>> result.${n}.txt
環境
リンク
良かったら読んでください.
Pythonにおけるソート
記事2: C言語 qsort()関数の結果も紹介しています.
sortプログラムはマージソートを用いている.
実装 sort.c