同じ関数を 2 回呼び出さない (メモ化あり)

WBOY
リリース: 2024-07-31 07:42:12
オリジナル
1140 人が閲覧しました

Never call the same function twice (with memoization)

ということで、メモ化という興味深い小さな概念を発見しました。

私はそれに関する記事を読み始めましたが、アイデアの尻尾を捉えたすぐにやめました。

その後、私は自分自身の、そして私が理解する方法で簡単な解決策を見つけ出すことにしました。

聞いたことがない方のために説明すると、メモ化とは関数の実行結果を保存するプロセスです。そのため、次回同じ引数を指定してその関数を実行するときに、小さな (またはそれほどでもない) キャッシュから結果を取得できます。

実際には、これはリソースを大量に消費する関数に役立ちます。余分なスペースをキャッシュとして使用するコストがかかります。ただし、コードの速度とそれを使用するユーザーのエクスペリエンスを向上させることができます。

JS コードを少しいじってみた結果、次の解決策が見つかりました:

const memoize = fn => {
  const cache = {}
  return (...args) => {
    const fnKey = `${fn.name}(${args})`;
    if(!cache[fnKey]) {
      cache[fnKey] = fn(...args);
    }

    return cache[fnKey]
  };
}
ログイン後にコピー
ログイン後にコピー

その後、次のように実行できます:

function _add(x, y) {
  console.log("function runs", x, y);
  return x + y;
}

const add = memoize(_add)

add(42, 69)
add(10, 15)
add(10, 15)
ログイン後にコピー

これにより、関数が 2 回実行されます (#1 と #2 の「add」呼び出し)。 3 番目の「add」呼び出しは #2 の呼び出しと同じなのでキャッシュを使用します。

'function runs' 42 69
'function runs' 10 15
ログイン後にコピー

「関数実行」 10 15 が 1 回だけ呼び出されていることがわかります。これは、2 回目に呼び出すとキャッシュが使用されるためです。

ここで何が起こっているのかを簡単に説明しましょう。

この例では、クロージャ メカニズムを利用してキャッシュを保存します。

const memoize = fn => {
  const cache = {}
  return () => {

  };
}
ログイン後にコピー

これにより、パーティのキングである「fn」引数をスローすることができます。これはまさに操作したい関数であるため、スコープの下に移動し、それぞれの実行を「リッスン」することができます。

私は本当に最も単純かつ素朴な方法でそれを書きました。したがって、キャッシュのキーとして引数を含む関数名を使用し、その実行結果を値として使用します。

つまり、以下を実行します:

add(2, 2)
ログイン後にコピー

結果

// Our cache
{
  'add(2, 2)': 4
}
ログイン後にコピー

キャッシュ値。

これが「正しい方法」で行うべき正確な方法ではない可能性があることは承知しています。ただし、この演習と記事のアイデアは、十分にテストされた安全でエッジケースのないソリューションに関するものではありません。

これは学習と簡単な実装に関するものです。コンセプトについて。したがって、現時点では実装の詳細には焦点を当てていません。

ここで、最初に関数呼び出しのキーを見つけます。

const memoize = fn => {
  const cache = {}
  return (...args) => {
    const fnKey = `${fn.name}(${args})`;
  };
}
ログイン後にコピー

関数の実行結果をキャッシュに保存するために使用します。

次に、このキー (fnKey) が既に存在するかどうかを確認します。そうでない場合は、渡された関数の実行の結果としてキーをその値で設定します。

最終的には常にキャッシュから結果を返します。そのため、実際には、memoize メソッドに渡された関数の実行は常にクロージャ (「キャッシュ」オブジェクト内) で終了します。

現在はこのオブジェクトのみを操作します:

const memoize = fn => {
  const cache = {}
  return (...args) => {
    const fnKey = `${fn.name}(${args})`;
    if(!cache[fnKey]) {
      cache[fnKey] = fn(...args);
    }

    return cache[fnKey]
  };
}
ログイン後にコピー
ログイン後にコピー

それで終わりです。

これから、それを「適切に」行う方法を見ていきます。でも、もしこれが面白いと思ったら、私に知らせてください。このアプローチで不明な点や間違っている点がある場合は (好みに合わせて)、コメントをドロップして、それについて話し合いましょう。

ありがとう、また会いましょう!

以上が同じ関数を 2 回呼び出さない (メモ化あり)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート