Pythonの辞書に対称入力データのキャッシュのための適切なfrozensetのですか?
質問
タイトル多かれ少なかれ、すべてのことを言います:
Iは、例えば、二つの引数に対称的な入力を取る機能を有しています
のようなものdef f(a1, a2):
return heavy_stuff(abs(a1 - a2))
今、私はいくつかのキャッシュ方法を紹介したいと思います。それは正しいだろう/ニシキヘビ/合理的に効率的にこのような何かを:
cache = {}
def g(a1, a2):
fs =frozenset((tuple(a1), tuple(a2)))
if fs not in cache:
cache[fs] = f(a1, a2)
return cache[fs]
または一部のより良い方法があるでしょう?
編集: A1とA2は、numpyの配列の行であるかもしれません。それの理由はI各タプルでそれらをラップします。
解決
Pythonは常にあなたが関数に渡しているすべての引数を計算し、唯一それが関数を呼び出すん。言い換えれば、他のほとんどの言語と同様、Pythonはその評価に「熱心」である(主な例外今日はおそらくHaskellのですが、それはあなたを助けない; - )。
setdefault
ので、キャッシングのための非常にの不適当なアプローチです!あなたがするたびに
cache.setdefault(akey, f(x, y))
あなたがしているの最初のの多分床にその計算結果を落とすのそしてを、そのすべての計算コストで、f(x, y)
を呼び出します。これは、キャッシュが完全に無効になります。
むしろは、常にそれを実行します。
akey = whatever(x, y)
if akey not in cache:
cache[akey] = f(x, y)
return cache[akey]
など - いくつかの他の可能なイディオムは、存在している場合は特に、例えばあなたはそのf
がNone
を返すことはありません知っています:
result = cache.get(akey)
if result is None:
result = cache[akey] = f(x, y)
return result
キーの計算のための適切なwhatever
あなたはそのf
が対称である知っていることを考えると、何の二次の問題については、私はfrozenset
はおそらくOKだと思います。ただし(x
とy
のコンポーネントは、同等のほか、ハッシュ可能であれば - すなわち、それは複素数と動作しないでしょう)あなたが
ta1 = tuple(a1)
ta2 = tuple(a2)
if ta1 > ta2: key = ta1, ta2
else: key = ta2, ta1
相対的な性能は、ハッシュの対、a1
とa2
の項目を比較したコストに依存します。違いとにかく、マイナーである可能性が高いです。