Haskell とメモリ

This entry was posted by on Wednesday, 14 June, 2006
>関数型言語脳に侵されていると、メモリ効率とかは比較的どうでもいいという考え方になってくる。そういうことは処理系が考えればいいので、プログラマはあんまり気にしなくてよくなる。 > >のだが、さすがにどうかと気になるところもあって、その辺の話。 > > >Crypto > というライブラリには MD5 値を計算する Data.Digest.MD5 というモジュールがあるのだが、ここで用意されているのは hash :: > >こないだの akr さんの発表ではないが、 MD5 値はファイルに対して計算することが多い。たとえば、現在あるディレクトリのなかのファイルの MD5 値を次々に計算していくというプログラムは次のようになるだろう。 > >import Control.Monad
import Data.Digest.MD5
import System.Directory

getHash fname =
do flag <- doesDirectoryExist fname
unless flag $ do c <- readFile fname
hash c `seq` return ()
main = do d <- getDirectoryContents "."
mapM_ getHash d > >この場合、ファイル全体の文字列を持つことになってしまう。確かに本来的には必要ないが、ちゃんと GC できないようで、利用するメモリ量は際限なく増えていき、ロードアベレージが上昇していく。これでは、さすがに使いものにならない。 > >で、 ruby だとこう書ける。 > >require 'digest/md5'

Dir.new(".").each do |fname|
unless FileTest.directory?(fname)
dgst = Digest::MD5.new
File.open(fname) do |fio|
buf = ""
dgst << buf while fio.read(256, buf)
end
end
# puts dgst.hexdigest
end > >これは Ruby リファレンスマニュアルからの借用。ファイルごとに MD5 オブジェクトが作られるのがちょっと嬉しくないがそれはさておき、この方式だとファイルまるごとを持つ必要がなく、実際、ほとんどメモリも必要とせずに動作を完了する。 > >MD5Aux の中からもうちょっと使い勝手のいい部分を取り出し、適当な文字列の断片を追加していく方式が望ましいように思うのだが、さて、どうしたものか。 > >追記: とりあえず SHA1 のコードを見たらわかったので、それをもとに作ってみた→
>http://www.city5.org/haskellprog/SHA1.hs >。短いコードではじゃっかん遅くなるが、ある程度の長さであれば文句なしに速くなった(いろいろ無駄を省いたからだろうけど、速いのは)。あと、速くなったといっても他言語にくらべれば重たいので、実用的にはやっぱ OpenSSL とかを使った方がいいのかなー。 >

Comments are closed.