Optimization of sort()

Perlの最適化器はかなり頑張ってsort()の最適化を試みている。具体的には,配列をその場で直接ソートする場合,数値または整数でソートする場合,ソートブロックの$aと$bを単純に入れ替えた場合において,最適化された高速なバージョンが使われる。
以下はすべて5.10.0で確認した。

配列を直接ソートする場合

ソート後のリストを元の配列に代入するケース(たとえば"@array = sort @array")では,sort()に渡された配列を直接並び替えるため,メモリと速度の両方で勝る。

確認コード:

$ perl -MO=Concise,-exec -e '@a=sort@a'
# ...
7  <@> sort lK/INPLACE
# ...

ソートオペレータにおける「INPLACE」というフラグがこの最適化の表れである。

数値でソートする場合

ソートブロックでの数値による比較(たとえば"sort{ $a <=> $b } @array")は最適化され,Cで実装された高速なバージョンが使われる。

確認コード:

$ perl -MO=Concise,-exec -e '@a=sort{$a<=>$b}@a'
#...
7  <@> sort lK/INPLACE,NUM
# ...

ソートオペレータにおける「NUM」というフラグがこの最適化の表れである。

整数でソートする場合

integerプラグマによって整数による比較を行うことができるが,これは汎用数値比較よりもさらに高速なコードを生成する。

確認コード:

$ perl -MO=Concise,-exec -e 'use integer; @a=sort{$a<=>$b} @a'
#...
7  <@> sort lK/INPLACE,INT,NUM
# ...

ソートオペレータにおける「INT」というフラグがこの最適化の表れである。

逆順にソートする場合

ソートブロックの$aと$bを交換した逆順ソートにも対応している。

確認コード

$ perl -MO=Concise,-exec -e '@a =sort{$b cmp $a}@a'
#...
7  <@> sort lK/DESC,INPLACE
#...

ソートオペレータにおける「DESC」というフラグがこの最適化の表れである。

また,reverse sortにも対応しているが*1,DESCが初めから逆順にソートするのに対し,reverse sortは一旦ソートしてから逆順に並び返すためDESCの方が高速である。

*1:その場合はREVフラグが立つ。