この初版は Lua 5.0 のために書かれました。それ以降のバージョンでも概ね関連していますが、若干の違いがあります。
第 4 版は Lua 5.3 を対象にしており、Amazon やその他の書店で入手可能です。
本を購入することで、Lua プロジェクトのサポートにも貢献できます。
![]() |
プログラミング inLua | ![]() |
パート II. テーブルとオブジェクト 第 17 章. 弱参照テーブル |
一般的なプログラミング技術として、スペースを時間で補う手法があります。関数の結果をメモ化して後から同じ引数で関数を呼び出すときに結果を再利用すれば、一部の関数を高速化できます。
Lua コードを含む文字列を持ったリクエストを受け付ける汎用サーバーを考えてみてください。リクエストを受け取るたびにサーバーは文字列に対して loadstring
を実行し、生成された関数を呼び出します。ただし、loadstring
は高価な関数で、サーバーに対する一部のコマンドは頻繁に実行されます。一般的なコマンドが "closeconnection()"
のように繰り返し何度も loadstring
を呼び出す代わりに、サーバーは補助的なテーブルを使用して loadstring
からの結果をメモ化できます。loadstring
を呼び出す前、サーバーはテーブル内の文字列にすでに変換があるかどうかを確認します。文字列が見つからなかった場合(その場合のみ)、サーバーは loadstring
を呼び出し、結果をテーブルに格納します。この動作を新しい関数にまとめることができます
local results = {} function mem_loadstring (s) if results[s] then -- result available? return results[s] -- reuse it else local res = loadstring(s) -- compute new result results[s] = res -- save for later reuse return res end end
このスキームでは、かなりの節約になります。ただし、予期しない無駄が生じる可能性もあります。コマンドによっては何度も繰り返されるものがありますが、ほとんどのコマンドは一度しか発生しません。徐々にテーブル results
には、サーバーがこれまで受信したすべてのコマンドとそのそれぞれのコードが蓄積されていきます。時間が経つと、サーバーのメモリが枯渇します。弱参照テーブルは、この問題に対する簡単な解決策です。テーブル results
の値が弱ければ、ガベージコレクションサイクルごとにその時点で使用されていないすべての変換が削除されます(つまり、事実上すべてのことです)
local results = {} setmetatable(results, {__mode = "v"}) -- make values weak function mem_loadstring (s) ... -- as before実際、インデックスは常に文字列であるため、必要に応じてテーブルを完全に弱くすることができます
setmetatable(results, {__mode = "kv"})最終結果はまったく同じです。
メモ化テクニックはオブジェクトの一意性を確保する場合にも役立ちます。たとえば、フィールド red
、green
、blue
がある何らかの範囲を持つテーブルとして色を表すシステムがあるとします。ナイーブなカラーファクトリーは新しいリクエストごとに新しい色を生成します。
function createRGB (r, g, b) return {red = r, green = g, blue = b} endメモ化テクニックを使用すると同じ色に同じテーブルを再利用できます。各色の一意なキーを作成するには、セパレーターを間に挟んで色インデックスを連結するだけです。
local results = {} setmetatable(results, {__mode = "v"}) -- make values weak function createRGB (r, g, b) local key = r .. "-" .. g .. "-" .. b if results[key] then return results[key] else local newcolor = {red = r, green = g, blue = b} results[key] = newcolor return newcolor end endこの実装における興味深い結果として、ユーザーは原始型の等価演算子を使用して色を比較できることが挙げられます。なぜなら、2 つの共存する等しい色は常に同じテーブルで表されるからです。場合によっては、ガベージコレクターのサイクルにより
results
テーブルがクリアされるため、同じ色が異なるテーブルで表される可能性があることに注意してください。ただし、特定の色が使用されている限りは、results
から削除されません。したがって、ある色が新しい色と比較されるのに十分な長さ生き残ると、その表現も新しい色によって再利用されるのに十分な長さ生き残ることになります。著作権 © 2003–2004 Roberto Ierusalimschy。すべての権利を保有します。 | ![]() |