第6章 より早く、より高速で、より小さく、より慎ましくあるための助言

目次

6.1. より早く: プログラムを素早く生成する
6.2. より速く: 高速に動作するプログラムを作る
6.3. より小さく: 小さいプログラムを作る
6.4. より慎ましく: 少ないヒープで動作するプログラムを作る

ここに加えるのに良い「有用なヒント」があるなら、是非教えてください!

6.1. より早く: プログラムを素早く生成する

-Oや(特に)-O2を使わない

これらのオプションを使うということは、より良い品質のコードのためなら長いコンパイル時間も甘受する、と言っているのに等しい。

-Oなしの通常のコンパイルではGHCは驚くほど速いですよ!

たくさんのメモリを使う

ヒープ空間のためにメモリを多く使う(合理的な範囲内で)と、GHCのGC回数を減らし、結果としてコンパイル時間を減らすことができる。-Rghc-timingオプションを使うと、GCの動作報告が得られる。(この場合も、安かろう悪かろうな+RTS -S -RTSオプションを使ってGC統計情報を直接標準エラー出力に送ることもできる。)

全体のうち20%以上の時間ををGCで使っているなら、メモリを増やすのが効果的かもしれない。これには-H<size>オプションを使う。コンパイラのデフォルトの確保領域の大きさを増やすのも効果的かもしれない。これには、+RTS -A<size> -RTSオプションを使う。

GHCのメモリの使いかたに改善が見られない場合は、バグとして報告してほしい。

あまりたくさんのメモリを使わないこと!

GHCとその「同僚たち」(機械中の他のプロセス)が機械の実メモリの量を超えて使い始めると、機械は即座に「スラッシング」を始める。こうなるとみんな台無しである。コンパイル時間は考えられないくらい酷くなる。どれくらいのページフォールトを経験しているかを計るにはcshの組込みのtimeのようなものを使うと良い。

もしあなたが仮想メモリ、スラッシング、ページフォールトというものを知らないなら、あるいはあなたの機械のメモリ構成を知らないなら、メモリの使いかたに関して賢く振る舞おうとしてはいけない。そんなことをしても人生(あなたのと、おそらく他人のも)がみじめになるだけである。

リンク時にはローカルのディスクを使う

Haskellのオブジェクトやライブラリは大きいものになる傾向があるので、リモートのファイルシステムとの間でビットをやりとりするのに多くの時間が掛かることがある。

リモートにマウントされたディスクを使って速い機械でコンパイルするのはとても理に適っている。そのあとで、ディスクが直接マウントされている遅い機械でリンクすればよいのだ。

不必要にReadを自動導出したり使ったりしない

これは醜く、しかも遅い。

GHCはある種の構造をコンパイルするときに遅くなる

この種の振る舞いはバグとして報告するのが良いと考える。そうすれば修正を試みることができるからである。

コンパイラのどの部分が悪戯しているかを知るには、-v2が便利だろう。