”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 切勿两次调用同一个函数(使用记忆功能)

切勿两次调用同一个函数(使用记忆功能)

发布于2024-08-15
浏览:777

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]删除
最新教程 更多>
  • 为什么使用 + 对字符串文字进行字符串连接失败?
    为什么使用 + 对字符串文字进行字符串连接失败?
    连接字符串文字与字符串在 C 中,运算符可用于连接字符串和字符串文字。但是,此功能存在限制,可能会导致混乱。在问题中,作者尝试连接字符串文字“Hello”、“,world”和“!”以两种不同的方式。第一个例子:const string hello = "Hello"; const...
    编程 发布于2024-11-05
  • React 重新渲染:最佳性能的最佳实践
    React 重新渲染:最佳性能的最佳实践
    React高效的渲染机制是其受欢迎的关键原因之一。然而,随着应用程序复杂性的增加,管理组件重新渲染对于优化性能变得至关重要。让我们探索优化 React 渲染行为并避免不必要的重新渲染的最佳实践。 1. 使用 React.memo() 作为函数式组件 React.memo() 是一个高...
    编程 发布于2024-11-05
  • 如何实现条件列创建:探索 Pandas DataFrame 中的 If-Elif-Else?
    如何实现条件列创建:探索 Pandas DataFrame 中的 If-Elif-Else?
    Creating a Conditional Column: If-Elif-Else in Pandas给定的问题要求将新列添加到 DataFrame 中基于一系列条件标准。挑战在于在实现这些条件的同时保持代码效率和可读性。使用函数应用程序的解决方案一种方法涉及创建一个将每一行映射到所需结果的函数...
    编程 发布于2024-11-05
  • 介绍邱!
    介绍邱!
    我很高兴地宣布发布 Qiu – 一个严肃的 SQL 查询运行器,旨在让原始 SQL 再次变得有趣。老实说,ORM 有其用武之地,但当您只想编写简单的 SQL 时,它们可能会有点让人不知所措。我一直很喜欢编写原始 SQL 查询,但我意识到我需要练习——大量的练习。这就是Qiu发挥作用的地方。 有了 Q...
    编程 发布于2024-11-05
  • 为什么 CSS 中的 Margin-Top 百分比是根据容器宽度计算的?
    为什么 CSS 中的 Margin-Top 百分比是根据容器宽度计算的?
    CSS 中的 margin-top 百分比计算当对元素应用 margin-top 百分比时,必须了解计算方式执行。与普遍的看法相反,边距顶部百分比是根据包含块的宽度而不是其高度来确定的。W3C 规范解释:根据W3C 规范,“百分比是根据生成的框包含块的宽度计算的。”此规则适用于“margin-top...
    编程 发布于2024-11-05
  • 如何解决 CSS 转换期间 Webkit 文本渲染不一致的问题?
    如何解决 CSS 转换期间 Webkit 文本渲染不一致的问题?
    解决 CSS 转换期间的 Webkit 文本渲染不一致在 CSS 转换期间,特别是缩放元素时,Webkit 中可能会出现文本渲染不一致的情况浏览器。这个问题源于浏览器尝试优化渲染性能。一种解决方案是通过添加以下属性来强制对过渡元素的父元素进行硬件加速:-webkit-transform: trans...
    编程 发布于2024-11-05
  • 使用 Reactables 简化 RxJS
    使用 Reactables 简化 RxJS
    介绍 RxJS 是一个功能强大的库,但众所周知,它的学习曲线很陡峭。 该库庞大的 API 界面,再加上向反应式编程的范式转变,可能会让新手不知所措。 我创建了 Reactables API 来简化 RxJS 的使用并简化开发人员对反应式编程的介绍。 例子 我们将构建...
    编程 发布于2024-11-05
  • 如何在 Pandas 中查找多列的最大值?
    如何在 Pandas 中查找多列的最大值?
    查找 Pandas 中多列的最大值要确定 pandas DataFrame 中多列的最大值,可以采用多种方法。以下是实现此目的的方法:对指定列使用 max() 函数此方法涉及显式选择所需的列并应用 max() 函数: df[["A", "B"]] df[[&q...
    编程 发布于2024-11-05
  • CI/CD 入门:自动化第一个管道的初学者指南(使用 Jenkins)
    CI/CD 入门:自动化第一个管道的初学者指南(使用 Jenkins)
    目录 介绍 什么是 CI/CD? 持续集成(CI) 持续交付(CD) 持续部署 CI/CD 的好处 更快的上市时间 提高代码质量 高效协作 提高自动化程度和一致性 如何创建您的第一个 CI/CD 管道 第 1 步:设置版本控制 (GitHub) 第 2 步:选择 CI/CD 工具 ...
    编程 发布于2024-11-05
  • TypeScript 如何使 JavaScript 在大型项目中更加可靠。
    TypeScript 如何使 JavaScript 在大型项目中更加可靠。
    介绍 JavaScript 广泛应用于 Web 开发,现在也被应用于不同行业的大型项目中。然而,随着这些项目的增长,管理 JavaScript 代码变得更加困难。数据类型不匹配、运行时意外错误以及代码不清晰等问题可能会导致查找和修复错误变得困难。 这就是TypeScript介入的地...
    编程 发布于2024-11-05
  • 如何使用PHP的password_verify函数安全地验证用户密码?
    如何使用PHP的password_verify函数安全地验证用户密码?
    使用 PHP 解密加密密码许多应用程序使用密码哈希等加密算法安全地存储用户密码。然而,在验证登录尝试时,将输入密码与加密的存储版本进行比较非常重要。加密问题password_hash 使用 Bcrypt,一种一元加密算法方式哈希算法,意味着加密的密码无法逆转或解密。这是一项安全功能,可确保即使数据库...
    编程 发布于2024-11-05
  • 学习 Vue 部分 构建天气应用程序
    学习 Vue 部分 构建天气应用程序
    深入研究 Vue.js 就像在 DIY 工具包中发现了一个新的最喜欢的工具——直观、灵活,而且功能强大得惊人。我接触 Vue 的第一个副业项目是一个天气应用程序,它教会了我很多关于框架功能以及一般 Web 开发的知识。这是我到目前为止所学到的。 1. Vue 入门:简单与强大 Vue...
    编程 发布于2024-11-05
  • NFT 预览卡组件
    NFT 预览卡组件
    ?刚刚完成了我的最新项目:使用 HTML 和 CSS 的“NFT 预览卡组件”! ?查看并探索 GitHub 上的代码。欢迎反馈! ? GitHub:[https://github.com/khanimran17/NFT-preview-card-component] ?现场演示:[https://...
    编程 发布于2024-11-05
  • Android 应用程序如何连接到 Microsoft SQL Server 2008?
    Android 应用程序如何连接到 Microsoft SQL Server 2008?
    将 Android 应用程序连接到 Microsoft SQL Server 2008Android 应用程序可以无缝连接到中央数据库服务器,包括 Microsoft SQL Server 2008。这种连接允许开发人员从其移动应用程序访问和管理存储在远程服务器上的数据。连接方法虽然提供的示例代码侧...
    编程 发布于2024-11-05
  • 以下是一些基于问题的标题选项,重点关注核心问题:

* C++ std::可选:为什么没有对引用类型进行专门化? (直接、切题)
* C++ std::option 中的引用类型
    以下是一些基于问题的标题选项,重点关注核心问题: * C++ std::可选:为什么没有对引用类型进行专门化? (直接、切题) * C++ std::option 中的引用类型
    C 中的可选:为什么没有对引用类型进行专门化?尽管在像 Boost 这样的库中存在对引用类型的专门化,C标准库的 std::Optional 不提供这样的功能。这一决定引发了对其理由和潜在替代机制的询问。遗漏背后的理由在讨论 n3406(可选提案)期间,有人提出了担忧关于包含可选参考文献。认识到这些...
    编程 发布于2024-11-05

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3