Android 指リスト編については、既に Haskell編、 Python編、 Python編(その2) が存在しているが、今度は C++ 編である。
が、 C++ では Haskell や Python のように、 interactive shell でお遊びをするあたりはさすがに再現できないので、 代わりに実行速度にこだわってみたい。
実行速度にこだわるというからには、 Python やら Haskell やらがどの程度の実行速度なのかをあらかじめ知っておく必要がある。 以前の記事では interactive shell で遊ぶために全てのパターンを列挙していたが、 今回については単純化のためパターン数の計算のみについて考えることとし、 最初から単純にパターン数を数え上げる方式にプログラムを若干変更の上計測する。
実行時間計測:Python
ベースのプログラムはPython編(その2)を用い、 nextList 関数を数え上げのみに限定しておく。
def nextList(i, rem):
return sum(
(nextList(s, rem - set([s])) for s in candidate(i, rem)),
1 if len(rem) <= 5 else 0)
print(nextList(0, frozenset(range(1, 10))))
time コマンドで実行にかかった時間を計測する。
% time python3 flistnum.py
389112
python3 flistnum.py 2.65s user 0.02s system 99% cpu 2.667 total
% time python3 flistnum.py
389112
python3 flistnum.py 2.66s user 0.00s system 99% cpu 2.659 total
% time python3 flistnum.py
389112
python3 flistnum.py 2.65s user 0.01s system 99% cpu 2.657 total
2.6秒強程度といったところ。
実行時間計測:Haskell
ベースのプログラムはもちろんHaskell編のものを使用する。 Python のときと同じように nextList 関数を数え上げのみに限定し、
nextList :: Int -> [Int] -> Int
nextList n rem =
foldr (+) (if length rem <= 5 then 1 else 0)
[nextList s (rem \\ [s]) | s <- candidate n rem]
main = print $ nextList 0 [1..9]
実行速度最適化オプション -O2 もつけてコンパイル後、計測する。
% time ./flistnum
389112
./flistnum 0.10s user 0.00s system 101% cpu 0.102 total
% time ./flistnum
389112
./flistnum 0.09s user 0.01s system 99% cpu 0.102 total
% time ./flistnum
389112
./flistnum 0.10s user 0.00s system 101% cpu 0.101 total
ちょっ...、わずか 0.1 秒...。
やるな、Haskell。 だが今回使うのは何しろ C++ である。コレに勝ってみせねばなるまい。
C++ の本当の実力を見せてやる!

