Haskellで最終ラウンド読み切りプログラムを書いた
C++で書いたやつと結果を照合しよう。
http://coderepos.org/share/browser/lang/python/saichugen/haskell/saichugen.hs?rev=22097
-
-
-
- -
-
-
$ time runghc saichugen.hs [237046,205614,261762,230880,189356] real 6m3.271s user 5m52.644s sys 0m3.304s
おそっ。C++で4秒、Pythonで120秒の処理にHaskellで720秒かかるとかおかしい。Haskellはネイティブにコンパイルするはずなのに。
-
-
-
- -
-
-
sumが引数の巨大なリストをメモリ上に展開させてしまうんじゃないか、と言われたのでこんなのを書いて置き換えて見たけどやっぱり6分かかるなぁ。
mysum :: Int -> [Int] -> Int mysum result [] = result mysum result (x:xs) = mysum (result + x) xs mysum0 = mysum 0
-
-
-
- -
-
-
id:voluntas に渡すためにほぼ逐語的にPythonに翻訳してみた。
http://coderepos.org/share/browser/lang/python/saichugen/haskell/experiment_python.py
$ time python experiment3.py [237046, 205614, 261762, 230880, 189356] real 4m5.894s user 4m0.529s sys 0m1.474s
あれー。Haskellで6分かかった処理がPythonだと4分だ。。
-
-
-
- -
-
-
お、Python版を作っている間にコメントが。ありがとうございます。seqを使って遅延評価をOFFにしてやればいいと、なるほど。試してみます。
-
-
-
- -
-
-
mysum :: Int -> [Int] -> Int mysum result [] = result -mysum result (x:xs) = mysum (result + x) xs +mysum result (x:xs) = (result + x) `seq` (mysum (result + x) xs) mysum0 = mysum 0
real 6m38.293s user 6m27.055s sys 0m3.467s
なんてこったい、かえって遅くなった。
add :: Score -> Score -> Score -add (Score x y z) (Score a b c) = (Score (x + a) (y + b) (z + c)) +add (Score x y z) (Score a b c) = (Score (x + a) (y + b) (z + c)) `seq` (Score (x + a) (y + b) (z + c)) --main = print $ (Score 1 2 3) `add` (Score 0 3 0)
real 6m51.495s user 6m34.909s sys 0m4.039s
な、なんだってー。seqの使い方が間違っているのだろうか。
-
-
-
- -
-
-
runghc はコンパイルせずに実行します。
おお、インタプリタなのですか?内部でコンパイルして実行していると思っていました。
real 0m14.942s user 0m13.614s sys 0m0.229s
おおー、格段に速くなりました。C++の3〜4倍程度になったので、Parallel化してクアッドコアで走らせればC++より少し速くなるかも。。
-
-
-
- -
-
-
実行時間から推測しますが、コンパイル時に-O2をつけておられないのでは?
real 0m1.843s user 0m1.803s sys 0m0.023s
おおお、C++で書いたバージョンより2倍くらい速くなりました!C++版はリストじゃなくてvectorで持っているのが遅いのかな。そうはいっても2倍も変わるのかな。。