Hatena2008-10-25
code:hatena
<body>
*1224895628*最中限Haskellで最終ラウンド読み切りプログラムを書いた C++で書いたやつと結果を照合しよう。
-----
||
$ time runghc saichugen.hs
real 6m3.271s
user 5m52.644s
sys 0m3.304s
||<
おそっ。C++で4秒、Pythonで120秒の処理にHaskellで720秒かかるとかおかしい。Haskellはネイティブにコンパイルするはずなのに。
-----
sumが引数の巨大なリストをメモリ上に展開させてしまうんじゃないか、と言われたのでこんなのを書いて置き換えて見たけどやっぱり6分かかるなぁ。
|haskell|
mysum :: Int -> Int -> Int mysum result [] = result
mysum result (x:xs) = mysum (result + x) xs
mysum0 = mysum 0
||<
-----
id:voluntas に渡すためにほぼ逐語的にPythonに翻訳してみた。
||
$ time python experiment3.py
real 4m5.894s
user 4m0.529s
sys 0m1.474s
||<
あれー。Haskellで6分かかった処理がPythonだと4分だ。。
-----
お、Python版を作っている間にコメントが。ありがとうございます。seqを使って遅延評価をOFFにしてやればいいと、なるほど。試してみます。
-----
|diff|
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
||<
なんてこったい、かえって遅くなった。
|diff|
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倍も変わるのかな。。
*1224917666*Pythonsumはeagerかどうか id:voluntasが「Erlangに移植するからHaskellのコードをわかりやすくPythonで書いて」と言ったので移植している。sumがeagerかどうか気になったので実験。
|python|
class Foo(object):
def __init__(self, i):
print "initialized %d" % i
self.i = i
def __add__(self, v):
print "added %d and %d" % (self.i, v.i)
return Foo(self.i + v.i)
def __del__(self):
print "deleted %d" % self.i
def gen():
for i in range(3):
yield Foo(i)
sum(gen(), Foo(100))
||<
実行結果
||
initialized 100
initialized 0
added 100 and 0
initialized 100
deleted 0
initialized 1
added 100 and 1
initialized 101
deleted 100
deleted 1
initialized 2
added 101 and 2
initialized 103
deleted 101
deleted 2
deleted 100
deleted 103
||<
101とか作った後ですぐ1や100のデストラクタが走っているね。eagerじゃないので安心して巨大なジェネレータ内包を突っ込んでも大丈夫だ。
*1224918982*python3.0のイースターエッグ
import antigravity
和訳すると
「ちよちゃんはなんで飛ぶのん?」「Pythonですから~」
*1224957031*PySpa
すごい、、JSでブラウザ上でKeyNoteみたいなものが動いている。。PowerPoint形式やPDFでエクスポートできる。すさまじい。JSってこんなことまで出来るんだ。。
おお、画像貼ろうとしたらネットから検索して貼れる。
ダウンロードはPowerPointとかPDFとか!
-----
DropBox 20GBだったかなんだったかを無料で使えるストレージ
-----
DjangoのドキュメントはJavaScriptで検索できるのか。便利便利。
</body>
<comments>
<comment>
<username>const ()</username>
<timestamp>1224917586</timestamp>
</comment>
<comment>
<username>s</username>
<body>runghc はコンパイルせずに実行します。</body>
<timestamp>1224931958</timestamp>
</comment>
<comment>
<username>tanakh</username>
<body>実行時間から推測しますが、コンパイル時に-O2をつけておられないのでは?</body>
<timestamp>1224939456</timestamp>
</comment>
<comment>
<username>const ()</username>
<body>書き換えるとしたら<br>mysum result (x:xs) = result' seq (mysum result' xs)<br> where result' = result + x<br>add (Score x y z) (Score a b c) = x' seq y' seq z' seq Score x' y' z'<br> where (x,y,z) = (x+a,y+b,z+c)<br>ではないかと。<br>最適化がそこまでやってくれるのかもしれないけど。</body>
<timestamp>1225092242</timestamp>
</comment>
</comments>