DSUとメモ化
DSUは結局、valueからkeyを取り出すfoo(value) ⇒ keyという関数があり、それをメモ化しているのと同じ意味だと思った。同じになるか実験してみた。
import time def memoize(func): D = {} def f(*args): if args in D: return D[args] res = func(*args) D[args] = res return res return f class Elem(object): def __init__(self, id): self.__id = id def __getattr__(self, attr): if attr == 'id': time.sleep(1) return self._Elem__id @memoize def getId(el): return el.id e1, e2, e5, e10 = Elem(1), Elem(2), Elem(5), Elem(10) L = [e1, e5, e10, e2] t = time.time() L.sort(lambda e1, e2: cmp(e1.id, e2.id)) # 工夫なし print time.time() - t, 'sec' t = time.time() L.sort(key=lambda el: el.id) # DSU print time.time() - t, 'sec' t = time.time() L.sort(lambda e1, e2: cmp(getId(e1), getId(e2))) # メモ化 print time.time() - t, 'sec'
実行結果:
10.0 sec 4.0 sec 4.0 sec
結果は当然DSUとメモ化で同じ(くらいの)パフォーマンスになった。この最初に初期化するという考え方は実際のコーディングでもよく使うが、このテクニック自体にも名前があれば分かりやすい。存在しないのだろうか?メモ化は、結局「関数と引数 ⇒ 返値」のハッシュであると思うが、用語の範囲としては以外と狭い気がする…。