」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 切勿兩次調用同一個函數(使用記憶功能)

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

發佈於2024-08-15
瀏覽:351

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

就是這樣。

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

謝謝,再見!

版本聲明 本文轉載於:https://dev.to/baypanic/never-call-the-same-function-twice-with-memoization-167f?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何在Java的全屏獨家模式下處理用戶輸入?
    如何在Java的全屏獨家模式下處理用戶輸入?
    Handling User Input in Full Screen Exclusive Mode in JavaIntroductionWhen running a Java application in full screen exclusive mode, the usual event ha...
    程式設計 發佈於2025-05-25
  • 找到最大計數時,如何解決mySQL中的“組函數\”錯誤的“無效使用”?
    找到最大計數時,如何解決mySQL中的“組函數\”錯誤的“無效使用”?
    如何在mySQL中使用mySql 檢索最大計數,您可能會遇到一個問題,您可能會在嘗試使用以下命令:理解錯誤正確找到由名稱列分組的值的最大計數,請使用以下修改後的查詢: 計數(*)為c 來自EMP1 按名稱組 c desc訂購 限制1 查詢說明 select語句提取名稱列和每個名稱...
    程式設計 發佈於2025-05-25
  • 在JavaScript中如何並發運行異步操作並正確處理錯誤?
    在JavaScript中如何並發運行異步操作並正確處理錯誤?
    同意操作execution 在執行asynchronous操作時,相關的代碼段落會遇到一個問題,當執行asynchronous操作:此實現在啟動下一個操作之前依次等待每個操作的完成。要啟用並發執行,需要進行修改的方法。 第一個解決方案試圖通過獲得每個操作的承諾來解決此問題,然後單獨等待它們: c...
    程式設計 發佈於2025-05-25
  • 為什麼HTML無法打印頁碼及解決方案
    為什麼HTML無法打印頁碼及解決方案
    無法在html頁面上打印頁碼? @page規則在@Media內部和外部都無濟於事。 HTML:Customization:@page { margin: 10%; @top-center { font-family: sans-serif; font-weight: ...
    程式設計 發佈於2025-05-25
  • `console.log`顯示修改後對象值異常的原因
    `console.log`顯示修改後對象值異常的原因
    foo = [{id:1},{id:2},{id:3},{id:4},{id:id:5},],]; console.log('foo1',foo,foo.length); foo.splice(2,1); console.log('foo2', foo, foo....
    程式設計 發佈於2025-05-25
  • 用戶本地時間格式及時區偏移顯示指南
    用戶本地時間格式及時區偏移顯示指南
    在用戶的語言環境格式中顯示日期/時間,並使用時間偏移在向最終用戶展示日期和時間時,以其localzone and格式顯示它們至關重要。這確保了不同地理位置的清晰度和無縫用戶體驗。以下是使用JavaScript實現此目的的方法。 方法:推薦方法是處理客戶端的Javascript中的日期/時間格式化和...
    程式設計 發佈於2025-05-25
  • 如何在php中使用捲髮發送原始帖子請求?
    如何在php中使用捲髮發送原始帖子請求?
    如何使用php 創建請求來發送原始帖子請求,開始使用curl_init()開始初始化curl session。然後,配置以下選項: curlopt_url:請求 [要發送的原始數據指定內容類型,為原始的帖子請求指定身體的內容類型很重要。在這種情況下,它是文本/平原。要執行此操作,請使用包含以下標頭...
    程式設計 發佈於2025-05-25
  • Java為何無法創建泛型數組?
    Java為何無法創建泛型數組?
    通用陣列創建錯誤 arrayList [2]; JAVA報告了“通用數組創建”錯誤。為什麼不允許這樣做? 答案:Create an Auxiliary Class:public static ArrayList<myObject>[] a = new ArrayList<my...
    程式設計 發佈於2025-05-25
  • MySQL中如何高效地根據兩個條件INSERT或UPDATE行?
    MySQL中如何高效地根據兩個條件INSERT或UPDATE行?
    在兩個條件下插入或更新或更新 solution:的答案在於mysql的插入中...在重複鍵更新語法上。如果不存在匹配行或更新現有行,則此功能強大的功能可以通過插入新行來進行有效的數據操作。如果違反了唯一的密鑰約束。 實現所需的行為,該表必須具有唯一的鍵定義(在這種情況下為'名稱'...
    程式設計 發佈於2025-05-25
  • 同實例無需轉儲複製MySQL數據庫方法
    同實例無需轉儲複製MySQL數據庫方法
    在同一實例上複製一個MySQL數據庫而無需轉儲在同一mySQL實例上複製數據庫,而無需創建InterMediate sqql script。以下方法為傳統的轉儲和IMPORT過程提供了更簡單的替代方法。 直接管道數據 MySQL手動概述了一種允許將mysqldump直接輸出到MySQL cli...
    程式設計 發佈於2025-05-25
  • Python讀取CSV文件UnicodeDecodeError終極解決方法
    Python讀取CSV文件UnicodeDecodeError終極解決方法
    在試圖使用已內置的CSV模塊讀取Python中時,CSV文件中的Unicode Decode Decode Decode Decode decode Error讀取,您可能會遇到錯誤的錯誤:無法解碼字節 在位置2-3中:截斷\ uxxxxxxxx逃脫當CSV文件包含特殊字符或Unicode的路徑逃...
    程式設計 發佈於2025-05-25
  • 如何使用PHP將斑點(圖像)正確插入MySQL?
    如何使用PHP將斑點(圖像)正確插入MySQL?
    essue VALUES('$this->image_id','file_get_contents($tmp_image)')";This code builds a string in PHP, but the function call fil...
    程式設計 發佈於2025-05-25
  • Python不會對超範圍子串切片報錯的原因
    Python不會對超範圍子串切片報錯的原因
    在python中用索引切片範圍:二重性和空序列索引單個元素不同,該元素會引起錯誤,切片在序列的邊界之外沒有。 這種行為源於索引和切片之間的基本差異。索引一個序列,例如“示例” [3],返回一個項目。但是,切片序列(例如“示例” [3:4])返回項目的子序列。 索引不存在的元素時,例如“示例” [9...
    程式設計 發佈於2025-05-25
  • 如何使用node-mysql在單個查詢中執行多個SQL語句?
    如何使用node-mysql在單個查詢中執行多個SQL語句?
    Multi-Statement Query Support in Node-MySQLIn Node.js, the question arises when executing multiple SQL statements in a single query using the node-mys...
    程式設計 發佈於2025-05-25
  • 如何有效地選擇熊貓數據框中的列?
    如何有效地選擇熊貓數據框中的列?
    在處理數據操作任務時,在Pandas DataFrames 中選擇列時,選擇特定列的必要條件是必要的。在Pandas中,選擇列的各種選項。 選項1:使用列名 如果已知列索引,請使用ILOC函數選擇它們。請注意,python索引基於零。 df1 = df.iloc [:,0:2]#使用索引0和1 ...
    程式設計 發佈於2025-05-25

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3