これは私がコンソールに得るものです:2GB上だ
ghci> sum $ takeWhile (<10000000) [1..]
49999995000000
(11.96 secs, 2174569400 bytes)
!私はsum
がすでに合計しているものを捨てることができると思います。どうやってこれを書くのですか?
これは私がコンソールに得るものです:2GB上だ
ghci> sum $ takeWhile (<10000000) [1..]
49999995000000
(11.96 secs, 2174569400 bytes)
!私はsum
がすでに合計しているものを捨てることができると思います。どうやってこれを書くのですか?
あなたは千万Integer
Sを作成し、リストの細胞がたくさんいます。また、コンパイラで実行した場合は、解釈されたコードを実行しているため、割り当てがやや減ります。
主な問題は、インタープリタがまったく最適化しないため、sum
は、巨大なサンクを構築する遅延型バリアントを使用することです。 sum
はそれだけで罰金消費したリストの一部を破棄し、それはそう
sum [1,2,3,4 ...]
が
その後(...((((0 + 1) + 2) + 3) + 4) + ...)
となり、その後、結果を計算するために、サンクに置き換えます。 Integer
の追加は厳格であるため、これは最適な代替ではありません。
GHCiのプロンプトで、あなたはそれを修正する
Prelude Data.List> foldl' (+) 0 $ takeWhile (< 10000000) [1 .. ]
49999995000000
(1.41 secs, 1443355832 bytes)
を記述する必要があります。最適化された(もちろん、最適化された)プログラムでは、sum
は正常に動作します。
これはまさにだからここソリューションは、(import Data.List
を必要とする)foldl' (+) 0 $ takeWhile (<10000000) [1..]
可能性がありhttp://www.haskell.org/haskellwiki/Memory_leak
で説明しているもののように見えます。
私はちょうどハスケル初心者で好奇心が強いので、おそらくもっと良い解決策があります。 =^^ = (編集: :-P下の最初のコメントを読んでください)。
"GHCiでコードを実行しているときにスペースリークが発生した場合、解釈されたコードは' seq'を使用していてもコンパイルされたコードとは異なる動作をすることに注意してください。 - http://www.haskell.org/haskellwiki/Memory_leak – cacba