Haskellのacm.timus.ruから問題1330を解決しようとしています。基本的に、これは次のように要約されます。1)stdinから長さN(N <10 ^ 4)の配列Aと整数のMペア(M <10 ^ 5)を読み取ります。2)各(from、to)ペアについて、サブ配列A[from..to]の合計をstdoutに出力します。
SOでは、この質問の一部として2つを超えるURLを投稿することはできないため、以下のGithubリポジトリ内のファイルを参照します。
私は、ほとんどのコードを共有する2つのソリューションを考え出しました。最初のもの(1330_slow.hs)はプレリュード関数(getLine / read / words)を使用しており、やや遅いです:
$ ./bench.sh slow_hs
slow_hs
Time inside the program: 2.18
MD5 (output.slow_hs.txt) = 89bcf8fd69a7fce953595d329c8f033a
もう1つのソリューション(1330.hs)は、これらの関数を破棄し、同等のData.ByteString.Char8(B.getLine / B.readInt / B.words)に置き換えて、適切に実行します。
$ ./bench.sh hs
hs
Time inside the program: 0.27
MD5 (output.hs.txt) = 89bcf8fd69a7fce953595d329c8f033a
この問題の制限時間は500ミリ秒なので、270ミリ秒は十分に高速ですが(C ++やGoなどの他の言語の私のソリューションに匹敵します)、2180ミリ秒では問題は解決しません。では、なぜ私の最初の解決策はとてつもなく遅いのですか?Real World Haskellのプロファイリングのヒントに従ったとしても、これを理解することはできません(私が理解できたのは、時間の大部分がreadIntPair関数に費やされたということだけでしたが、あまり役に立ちませんでした)。
独自のテストを行いたい場合は、Python入力ジェネレーター(gen_test.py)と、Pythonがインストールされていない場合に備えて事前に生成された入力ファイル(input.txt)があります。そして、2つのソリューション間の差分(slow_fast_diff.txt)。