Performance degradation by view pattern
Published in
2 min readDec 26, 2016
view patternも使いどころが肝心らしいという話
私、view pattern大好き人間なので、こういうコードをよく書きます。
-- 何か副作用ありの[0 .. n-1]のループ
something :: Int -> IO Something
something ((< n) -> False)) = final task
something i = do
... (i + 1) ...
... (i + 1) ...
something (i + 1)x <- something 0
まあIOモナドの中で、しかもforMやmapMなどがうまくはまらないケースだと思ってください。if文やガードよりもコンパクトですし、これ自身が何か速度の低下になっているとは全然思ってないので、今まで多用してきました。
さて、この関数例では i + 1
を何度も計算しているので、最初に1回計算して束縛してしまえばいいじゃないかと考えたとします(cse何それ)。ここで、 let
等を持ち込まなくてもview patternを使えば1行目の中に置けるじゃないかということで、
something ((< n) -> False)) = final task -- 再掲
something ((+ 1) -> i) = do -- なんども計算するのでここでやってしまえ
... i ...
... i ...
something i
こんな風に書いて見ました。もちろんちゃんと動作するのですが、これによって明らかに速度の低下が起きます。この関数はプログラム全体の中でもクリチカルな箇所なのでこの変更だけで2割ほども遅くなってしまいました。
something ((+ 1) -> !i) = do ...
なんて姑息なことをやっても無駄。
何が違うんだ。引数のIntがunbox化できなくなったりするのだろうか。。。というところまでで力尽きました。