パスワードを忘れた? アカウント作成
481269 journal

krの日記: Haskellで速いwcを書いてみよう(2)

日記 by kr

前のエントリからの続きです。

まずはtanakh氏の跡を追ってみようということで、 氏の書いたHaskell版、C++版、C版のwcの実行速度を、手元のマシンで計測してみます。

まずはHaskell版。使ったコンパイラは、

% ghc --version
The Glorious Glasgow Haskell Compilation System, version 6.6.1

というものです。

早速、氏の「7月27日あたりで書いた全く直截的なコード」とあるものをそのままコピーして、コンパイルしました。 テスト用入力としては、手元にあってそこそこ大きいテキストファイルということで、 /usr/share/doc/en/books/handbook/book.txt(FreeBSD handbook)を喰わせてみました。

……が、いきなり挫折で、Stack space overflowと出て動きません。

実はこの結果は予想していました。読み込んだテキストをすべてメモリに保持して、行数・単語数・文字数をそれぞれ計算しているので、 まあ当然かなと。(ちなみにHaskellは文字列をUnicode文字のリストとして保持するので、そういうことをすると、やたらメモリを食います。)

念のため書いておくと、例えば単語数だけ表示するプログラムだったら、同じように書いてもちゃんと動きます。

-- prog1
main = getContents >>= putStrLn . show . length . words

一応この速度を測っておくと、以下のようでした。(2回目以降のコマンドラインと出力結果は省略)

% time ./prog1 < /usr/share/doc/en/books/handbook/book.txt
323341
0.767u 0.007s 0:00.80 95.0%     345+271k 0+0io 0pf+0w
0.758u 0.016s 0:00.80 95.0%     328+257k 0+0io 0pf+0w
0.772u 0.001s 0:00.80 96.2%     314+246k 0+0io 0pf+0w
0.766u 0.007s 0:00.80 95.0%     331+260k 0+0io 0pf+0w
0.752u 0.022s 0:00.80 96.2%     344+269k 0+0io 0pf+0w

実時間で0.80秒ですね。 一見、ファイルを全部読み込んでいるようにも見えますが、実際には1単語分の文字列を構築しては捨てていくので、最長単語が保持できるメモリさえあれば動きます。遅延評価万歳。

ただし行数と文字数を表示しない点で、今回のお題に合わないので、これはあくまで参考ということで。

続きます。

typodupeerror

皆さんもソースを読むときに、行と行の間を読むような気持ちで見てほしい -- あるハッカー

読み込み中...