これは私がコンソールに表示するものです:
ghci> sum $ takeWhile (<10000000) [1..]
49999995000000
(11.96 secs, 2174569400 bytes)
それは2GBを超えています!sum
私はそれがすでに合計したものは何でも捨てることができると想像します。これをどのように書きますか?
これは私がコンソールに表示するものです:
ghci> sum $ takeWhile (<10000000) [1..]
49999995000000
(11.96 secs, 2174569400 bytes)
それは2GBを超えています!sum
私はそれがすでに合計したものは何でも捨てることができると想像します。これをどのように書きますか?
あなたは1000万Integer
秒とたくさんのリストセルを作成しています。また、インタープリターされたコードを実行している場合、コンパイラーを介して実行すると、割り当てがいくらか減少します。
主な問題は、インタプリタがまったく最適化されていないことです。そのため、は巨大なサンクsum
を構築する怠惰なバリアントを使用します。正常に消費したリストの一部を破棄しますが、後で結果を計算するためにサンクに置き換えます。sum
sum [1,2,3,4 ...]
になります
(...((((0 + 1) + 2) + 3) + 4) + ...)
その後。Integer
sの追加は厳密であるため、これは最適な置換ではありません。
ghciプロンプトで、次のように書く必要があります
Prelude Data.List> foldl' (+) 0 $ takeWhile (< 10000000) [1 .. ]
49999995000000
(1.41 secs, 1443355832 bytes)
それを修正します。コンパイルされた(もちろん最適化された)プログラムでは、sum
正常に機能します。
これは、 http://www.haskell.org/haskellwiki/Memory_leakで説明されているものとまったく同じように見えます
したがって、ここでの解決策はfoldl' (+) 0 $ takeWhile (<10000000) [1..]
(必要なimport Data.List
)である可能性があります。
私はHaskellの初心者であり、好奇心旺盛だったので、おそらくもっと良い解決策があります。=^。^=(編集:以下の最初のコメントを読んでください:-P)