17

この質問について正確に何をグーグルするかわからないので、SOに直接投稿します:

  1. Haskell の変数は不変です
  2. 純粋な関数は、同じ引数に対して同じ値になる必要があります

somePureFunc somevar1 somevar2これら 2 つの点から、コードを 2 回呼び出した場合、最初の呼び出し時に値を計算することだけが意味があると推測できます。結果の値は、ある種の巨大なハッシュ テーブル (またはそれに類するもの) に格納でき、その後の関数呼び出しで参照できます。2 つの質問があります。

  1. GHC は実際にこのような最適化を行っているのでしょうか?
  2. もしそうなら、結果を調べるよりも計算を繰り返す方が実際に安価な場合の動作は何ですか?

ありがとう。

4

2 に答える 2

17

GHC は自動メモ化を行いません。GHC FAQ on Common Subexpression Elimination (まったく同じではありませんが、理由は同じだと思います) と、この質問への回答を参照してください。

自分でメモ化を行いたい場合は、Data.MemoCombinatorsをご覧ください。

メモ化のもう 1 つの見方は、怠惰を利用してメモ化を利用することです。たとえば、リスト自体を定義できます。以下の定義は、すべてのフィボナッチ数の無限リストです ( Haskell Wikiから取得) 。

fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

リストは遅延して実現されるため、以前の値を事前に計算 (メモ化) することに似ています。たとえばfibs !! 10、最初の 10 個の要素を作成すると、fibs 11はるかに高速になります。

于 2011-05-22T08:59:12.667 に答える
6

すべての関数呼び出しの結果を保存することは有効ですが(ハッシュ consingを参照)、巨大なスペース リークが発生する可能性があり、一般にプログラムの速度も大幅に低下します。実際に計算するよりも、テーブルに何かがあるかどうかを確認する方がコストがかかることがよくあります。

于 2011-05-22T13:02:46.963 に答える