0Pricing
Lua Academy · レッスン

クロージャによるメモ化

コストの高い関数の結果をクロージャ内のテーブルにキャッシュします。

「クロージャによるメモ化」はCoddyKit上の無料Lua Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLua Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Lua Academyコースには全4レッスンが含まれています。

メモ化とは

メモ化は、コストの高い関数呼び出しの結果をキャッシュし、同じ引数による再呼び出しではキャッシュ済みの結果を即座に返す仕組みです。

基本的なメモ化ラッパー

クロージャはcacheテーブルを保持します。初回の呼び出しでは計算して保存し、再度呼び出されたときは保存済みの値を返します。

local function memoize(fn)
  local cache = {}
  return function(x)
    if cache[x] == nil then
      cache[x] = fn(x)
    end
    return cache[x]
  end
end

メモ化されたフィボナッチ

再帰的なフィボナッチ関数をメモ化すると、時間計算量を指数時間から線形時間に削減できます。

local fib
fib = memoize(function(n)
  if n <= 1 then return n end
  return fib(n-1) + fib(n-2)
end)
print(fib(30))  -- 832040 (fast!)

複数引数のメモ化

引数が複数ある関数では、すべての引数からキャッシュキー文字列を作成します。

local function memoize2(fn)
  local cache = {}
  return function(a, b)
    local key = a .. "," .. b
    if cache[key] == nil then cache[key] = fn(a, b) end
    return cache[key]
  end
end

ネストしたキャッシュテーブル

引数の型が混在する場合は、各引数をキーにしたネストしたテーブルを使うと、文字列化せずにO(1)で検索できます。

local function nestedMemo(fn)
  local cache = {}
  return function(a, b)
    cache[a] = cache[a] or {}
    if cache[a][b] == nil then cache[a][b] = fn(a, b) end
    return cache[a][b]
  end
end

キャッシュの無効化

メモ化は、純粋関数(副作用がなく、同じ入力に対して同じ出力を返す関数)を前提とします。副作用のある関数は、キャッシュを慎重に無効化しない限り、メモ化すべきではありません。

TTLベースのメモ化

os.time()を使って有効期間のロジックを追加し、期限切れのキャッシュエントリを破棄します。

local function memoizeTTL(fn, ttl)
  local cache = {}
  return function(x)
    local entry = cache[x]
    if entry and os.time() - entry.time < ttl then
      return entry.value
    end
    cache[x] = {value = fn(x), time = os.time()}
    return cache[x].value
  end
end

弱い値のキャッシュ

弱い値を使うと、メモリが逼迫したときにキャッシュ結果をガベージコレクションできます。

local function memoizeWeak(fn)
  local cache = setmetatable({}, {__mode = "v"})
  return function(x)
    if cache[x] == nil then cache[x] = fn(x) end
    return cache[x]
  end
end

再帰的なメモ化パターン

相互再帰する関数では、再帰本体から使用される前にメモ化ラッパーを割り当てます。これにより、再帰でキャッシュが利用されます。

容量制限付きキャッシュ(LRUの概要)

メモリを制御するには、キャッシュが最大サイズを超えたときに最も長く使われていないエントリを追い出すLRUキャッシュを実装します。

実践でのメモ化

一般的な用途には、コストの高い数学的計算、データベースクエリ結果のキャッシュ、Luaパターンのコンパイル、設定ファイルの解析があります。

メモ化に関する質問

メモ化を純粋関数にのみ適用すべきなのはなぜですか?

まとめ:メモ化

メモ化は、クロージャが保持するキャッシュに引数キーごとの結果を保存し、重複した計算をなくします。メモリの安全性のために弱いテーブルを使い、時間に依存するキャッシュにはTTLを追加します。

よくある質問

「クロージャによるメモ化」レッスンは無料ですか?

はい。「クロージャによるメモ化」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Lua Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Lua Academyコースには全4レッスンが含まれています。

「クロージャによるメモ化」で何を学びますか?

コストの高い関数の結果をクロージャ内のテーブルにキャッシュします。 ブラウザで直接実行するハンズオンコードでLua Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Lua Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのLua Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「クロージャによるメモ化」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このLua Academyレッスンでコードを書いて実行できますか?

はい。すべてのLua Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Upvalueとは
  2. クロージャ間で共有されるUpvalue
  3. ファクトリー関数とジェネレーター
  4. クロージャによるメモ化
← Lua Academyに戻る