あああ、僕もうっかりしてました。
On Lispの
memoizeなんですけど。久々にGauche起動してValvallowさんに従って試してみたら、次のような結果になりました。あれ、全然速くなっていない……。
考えてみれば当然で、手続き
memoizeは呼び出す度に新しくレキシカル環境を作ります。と言う事は。
cacheに保存される筈のハッシュテーブルは、手続きmemoizeが呼び出される度に新しくクロージャの中で作られて、そしてmemoizeの起動が終了する度にその寿命を全うするわけです。従って、
hash-table-getの返り値は毎度必ず#fになる、って事です。これじゃあ意味無い。
んで、On Lispを良く見てみると、実は「敢えて」
memoizeとそれが受け取る関数引数を合わせて大域環境に束縛しているんです。これが手続き
memoizeの正しい使い方です。本に依ると、大域変数slowidに束縛されている以上、クロージャ、翻って使用されたハッシュテーブルが廃棄されません。ご覧になれば分かるでしょうが、一回目の大域変数
slowidに35を付けた時の呼び出しは遅いです。反面、クロージャ/ハッシュテーブルは依然と大域変数slowidに束縛されたまま、なんで、二回目の呼び出し時は高速なハッシュ検索により、時間が殆どかからず値を見つけ出している事が分かると思います。これが
memoizeの使い方です。
0 件のコメント:
コメントを投稿