質問

属性を読み取り、関数をメモする 。関数呼び出しのハッシュはキーとキャッシュになります( Velocity )関数を再度呼び出す代わりに、結果が返されます。簡単に、簡単に、簡単に。

すでに与えられました装飾された機能の副作用を検出できるようになりました。これは専門家でさえ「難しい問題」であることが判明しましたが、私は確かにそうではありません。次に、メモ化の候補となる他の関数を把握する必要があります。

  • パラメータとして複雑な参照型をとるメソッドはどうですか?
  • 呼び出し元のインスタンス内のデータに依存するメソッドはどうですか?

ActiveRecord風のデータオブジェクトが最後の1つに思い浮かびます。

メモ化をサポートするために1週間前のコードをリファクタリングする必要がありますか?

役に立ちましたか?

解決

すべての入力が値型または不変の参照型である場合、値型または参照型の新しいインスタンスを返す場合、および副作用がない場合にのみ、関数をメモできます。期間。

メモ化は、入力と出力の間の決定論的なマッピングに依存します。 a、b、およびcが同じ値を含む F(a、b、c)を呼び出すたびに、メモ化を可能にするために同じ結果を返す必要があります。

パラメータが参照型の場合、その値は変更されませんが、そのパラメータを使用する関数を複数回呼び出すと、異なる結果が生成される場合があります。簡単な例:

public int MyFunction(MyType t)
{
   return t.Value;
}

Console.WriteLine(MyFunction(t));
t.Value++;
Console.WriteLine(MyFunction(t));

同様に、関数がその外部の値に依存している場合、同じパラメーターでその関数を複数回呼び出すと、異なる結果が返される可能性があります:

int Value = 0;

public int MyFunction(int input)
{
   return Value;
}

Console.WriteLine(MyFunction(1));
Value++;
Console.WriteLine(MyFunction(1));

メモ化された関数が値または新しい参照型を返す以外のことを行う場合、heavenはあなたを助けます:

int Value = 0;

public int MyFunction(int input)
{
   Value++;
   return input;
}

その関数を10回呼び出すと、 Value は10になります。メモ化を使用するようにリファクタリングしてから10回呼び出すと、 Value は1になります。

状態をメモする方法を理解する道をたどり始めると、参照型をメモする関数を偽造できます。しかし、実際にメモしているのは、関数が機能する値のセットです。同様に、副作用を持つメモ化された関数をハッキングして、メモ化の前に副作用が発生するようにすることができます。しかし、これはすべてトラブルを懇願しています。

参照型をとる関数にメモ化を実装する場合、適切なアプローチは、値型でのみ機能する関数の一部をリファクタリングし、その関数をメモ化することです。例:

public int MyFunction(MyType t)
{
   return t.Value + 1;
}

これ:

public int MyFunction(MyType t)
{
   return MyMemoizableFunction(t.Value);
}

private int MyMemoizableFunction(int value)
{
   return value + 1;
}

メモ化を実装する他のアプローチは、a)より不明瞭な手段を介して同じことを行うか、b)動作しません。

他のヒント

まあ、理論的には、どの関数もメモ化の候補です。ただし、メモ化はスペースと速度のトレードについてです-

一般に、これは、関数が答えを計算するために必要な状態または依存する状態が多いほど、スペースのコストが高くなり、メソッドをメモするのが望ましくないことを意味します。

どちらの例も、基本的に、より多くの状態を保存する必要がある場合です。これには2つの副作用があります。

最初に、より多くの情報を保存する必要があるため、関数をメモするためにより多くのメモリ空間が必要になります。

第二に、スペースが大きいほど回答のルックアップのコストが高くなり、結果が以前に保存されたかどうかを見つけるコストが高くなるため、メモされた関数の速度が低下する可能性があります。

一般に、回答の計算に非常に高いコストが発生しない限り、可能な入力が少なく、ストレージ要件が低い関数のみを検討する傾向があります。

これは漠然としていることは承知していますが、これは「芸術」の一部です。アーキテクチャで。 「正しい」というものはありません。両方のオプション(メモ機能と非メモ機能)、プロファイリング、測定を実装せずに答えます。

関数 Foo のメモ化を提供するAOPソリューションを提供する方法を既に考えているので、理解するために残っているものはありますか?

はい、それが依存するすべてのものが不変である限り、任意の複雑さのオブジェクトをパラメーターとしてメモ化された関数に渡すことができます。繰り返しますが、これは現時点では静的に発見するのは簡単ではありません。

質問についてユーザーにアドバイスするために、コードを静的に調べることができるという考えにまだ結婚していますか? / p>

それを要件の1つにすると、これまで何年も続いたグローバルな研究活動に参加することになります。あなたがどれほど野心的であるかによりますね。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top