2004年02月20日

ソートの高速化

Perlで作っていたプログラムのCSVデータソートがあまりにも重い・・・
1万件ぐらいのソートをさせるとCPU全部喰らったあげく3秒ぐらい掛かります(苦笑)

プログラムは下記のような感じでsort条件を関数化することで切り出してたのですが、さすがに限界を感じて別の方法を模索しました。

@sortedcsv = sort {&sortsplt(3,0)} @orgcsv;

sub sortsplt{
 my ($cell,$order) = @_;
 my @aa = split(/,/,$a);
 my @bb = split(/,/,$b);
 unless($order){
  return ($aa[$cell] <=> $bb[$cell]);
 }else{
  return ($bb[$cell] <=> $aa[$cell]);
 }
}
すると下記のサイトを発見
  • Schwartzian Transformは、無名配列を使うことによって中間データを保持するため作業用 の配列を特別に用意する必要がない、すべての処理を簡潔に記述することができるといった 特徴があります。しかし、無名配列を使用しているために、無名配列から要素を取り出すと いうオーバーヘッドが生じてしまいます。このため、次のように作業用の配列を用意して行 なう方法の方が実行速度が速いです。 @tmp = map {(split /,/)[2]} @LIST; @LIST = @LIST[sort {$tmp[$a] cmp $tmp[$b]} 0 .. $#tmp];
map?

使ったこと無い関数だったので調べてみると

こんな便利な関数あったのか_| ̄|○

早速上記の例の用にソート構文を書き換えて見たら3秒掛かっていた処理がCPU負荷10%以内でほぼ一瞬で終わるようになりました(^^;

っていうか、これって「perldoc -f sort」を見ると乗っているみたいです(爆)
ヘルプはちゃんと読まないとダメですね。ほんと

まだまだPerlマスターへの道は遠いなぁ・・・
(というか今までソートはDB側に任せっきりにしていたバチです(笑))

Posted by Takuchan at 2004年02月20日 09:41 | トラックバック(2)