首頁  >  文章  >  web前端  >  切勿兩次調用同一個函數(使用記憶功能)

切勿兩次調用同一個函數(使用記憶功能)

WBOY
WBOY原創
2024-07-31 07:42:121083瀏覽

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)

這會導致函數執行兩次(#1 和 #2 'add' 呼叫)。第三次「新增」呼叫將使用緩存,因為它與#2 呼叫相同。

'function runs' 42 69
'function runs' 10 15

您可以看到 'function running' 10 15 只被呼叫一次。這是因為當我們第二次呼叫它時,快取正在被使用。

現在讓我們快速分解這裡發生的事情。

在這個例子中我們利用閉包機制來儲存快取。

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]
  };
}

就是這樣。

現在我要去看看應該如何「正確」地完成它。但如果您覺得這很有趣,請告訴我。如果這種方法有任何不清楚或錯誤的地方(根據您的口味),請刪除評論,讓我們討論一下。

謝謝,再見!

以上是切勿兩次調用同一個函數(使用記憶功能)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
上一篇:NodeJS + ROHC下一篇:NodeJS + ROHC