Javascript中如何实现函数缓存?函数缓存有哪些应用场景?

#一、是什么

函数缓存,就是将函数运算过的结果进行缓存

本质上就是用空间(缓存存储)换时间(计算过程)

常用于缓存数据计算结果和缓存对象

解释

const add = (a,b) => a+b; const calc = memoize(add); // 函数缓存 calc(10,20);// 30 calc(10,20);// 30 缓存

缓存只是一个临时的数据存储,它保存数据,以便将来对该数据的请求能够更快地得到处理

#二、如何实现

实现函数缓存主要依靠闭包、柯里化、高阶函数,这里再简单复习下:

#闭包

闭包可以理解成,函数 + 函数体内可访问的变量总和

解释

(function() { var a = 1; function add() { const b = 2 let sum = b + a console.log(sum); // 3 } add() })()

add函数本身,以及其内部可访问的变量,即 a = 1,这两个组合在⼀起就形成了闭包

#柯里化

把接受多个参数的函数转换成接受一个单一参数的函数

解释

// 非函数柯里化 var add = function (x,y) { return x+y; } add(3,4) //7 // 函数柯里化 var add2 = function (x) { //**返回函数** return function (y) { return x+y; } } add2(3)(4) //7

将一个二元函数拆分成两个一元函数

#高阶函数

通过接收其他函数作为参数或返回其他函数的函数

解释

function foo(){ var a = 2; function bar() { console.log(a); } return bar; } var baz = foo(); baz();//2

函数 foo 如何返回另一个函数 barbaz 现在持有对 foo 中定义的bar 函数的引用。由于闭包特性,a的值能够得到

下面再看看如何实现函数缓存,实现原理也很简单,把参数和对应的结果数据存在一个对象中,调用时判断参数对应的数据是否存在,存在就返回对应的结果数据,否则就返回计算结果

如下所示

解释

const memoize = function (func, content) { let cache = Object.create(null) content = content || this return (...key) => { if (!cache[key]) { cache[key] = func.apply(content, key) } return cache[key] } }

调用方式也很简单

const calc = memoize(add);
const num1 = calc(100,200)
const num2 = calc(100,200) // 缓存得到的结果

过程分析:

  • 在当前函数作用域定义了一个空对象,用于缓存运行结果
  • 运用柯里化返回一个函数,返回的函数由于闭包特性,可以访问到cache
  • 然后判断输入参数是不是在cache的中。如果已经存在,直接返回cache的内容,如果没有存在,使用函数func对输入参数求值,然后把结果存储在cache

#三、应用场景

虽然使用缓存效率是非常高的,但并不是所有场景都适用,因此千万不要极端的将所有函数都添加缓存

以下几种情况下,适合使用缓存:

  • 对于昂贵的函数调用,执行复杂计算的函数
  • 对于具有有限且高度重复输入范围的函数
  • 对于具有重复输入值的递归函数
  • 对于纯函数,即每次使用特定输入调用时返回相同输出的函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/60088.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flink-Kafka-Connector

Apache Flink 是一个用于处理无界和有界数据的开源流处理框架。它支持高吞吐量、低延迟以及精确一次的状态一致性等特性。Flink 社区提供了丰富的连接器(Connectors)以方便与不同的数据源进行交互,其中就包括了 Apache Kafka 连接器。 Apach…

Maven的依赖管理、传递、冲突、父子工程的继承和聚合

目录 一、基于IDEA 进行Maven依赖管理 (一)依赖管理概念 (二)Maven工程核心信息配置和解读(GAVP) (三)Maven工程依赖管理配置 1.依赖管理和依赖添加 2.依赖版本统一提取和维护 (四)依赖范围 (五)Maven工程依赖下载失败错误解决(重点…

iOS SmartCodable 替换 HandyJSON 适配记录

前言 HandyJSON群里说建议不要再使用HandyJSON,我最终选择了SmartCodable 来替换,原因如下: 首先按照 SmartCodable 官方教程替换 大概要替换的内容如图: 详细的替换教程请前往:使用SmartCodable 平替 HandyJSON …

1.2 图像处理基本操作

在本实战中,我们将学习如何使用OpenCV进行基本的图像处理操作。首先,我们将通过cv2.imread()函数读取图像,并使用cv2.imshow()在窗口中显示它。接着,我们将探索如何通过cv2.imwrite()保存图像,并设置不同的参数以控制图…

Flink 状态精准一次性特性

Flink 的一个重大价值在于, 它既保证了 exactly-once ,也具有低延迟和高吞吐 的处理能力 。 1.端到端(End-To-End)状态一致性 端到端的一致性保证,意味着结果的正确性贯穿了整个流处理应用的始终;每 一…

【图像去噪】论文精读:SUNet: Swin Transformer UNet for Image Denoising

请先看【专栏介绍文章】:【图像去噪(Image Denoising)】关于【图像去噪】专栏的相关说明,包含适配人群、专栏简介、专栏亮点、阅读方法、定价理由、品质承诺、关于更新、去噪概述、文章目录、资料汇总、问题汇总(更新中) 文章目录 前言AbstractI. INTRODUCTIONII. RELATE…

使用Python实现音频降噪

在音频处理领域,背景噪声是一个常见的问题。为了提高音频的质量,我们需要对音频进行降噪处理。本文将介绍如何使用 Python 实现音频降噪。 依赖库安装 在开始之前,我们需要安装以下依赖库: pydub:用于音频文件的读取…

从经典到应用:探索 AlexNet 神经网络

引言 在 2012 年,深度学习领域迎来了一个历史性时刻——AlexNet 的问世。由 Alex Krizhevsky 及其团队提出的 AlexNet 是一种深度卷积神经网络模型,它在 ImageNet 大规模视觉识别挑战赛(ILSVRC)中取得了突破性成果,将…

与AMD GPU上的对比语言-图像预训练(CLIP)模型交互

Interacting with Contrastive Language-Image Pre-Training (CLIP) model on AMD GPU — ROCm Blogs 2024年4月16日,由Sean Song撰写. 引言 对比语言-图像预训练(CLIP)是一种多模态深度学习模型,连接视觉和自然语言。它在Open…

I/O操作完成事件

本文内容由智谱清言产生。 在计算机编程中,I/O(输入/输出)操作完成事件是指一个I/O操作(如读取文件、写入数据库、网络通信等)已经完成的通知。这种事件通常由操作系统或框架生成,以通知应用程序或程序中的…

2024年第四届“网鼎杯”网络安全比赛---朱雀组Crypto- WriteUp

2024年第四届“网鼎杯”网络安全比赛---朱雀组Crypto-WriteUp Crypto:Crypto-2:Crypto-3: 前言:本次比赛已经结束,用于赛后复现,欢迎大家交流学习! Crypto: Crypto-2: …

下载mysql的jar,添加至jmeter中,编写jdbc协议脚本1106

下载jar包: 步骤1:进入maven仓库官网https://mvnrepository.com/ 步骤2:搜索实际的数据库 步骤3:点击 Mysql connnector/J 步骤5、查看数据库的版本号,选择具体版本,我的是mysql 8.0.16,下图,…

IntelliJ IDEA的快捷键

IntelliJ IDEA 是一个非常强大的集成开发环境,它提供了大量的快捷键来加速开发者的日常工作。这里为您整理了一份 IntelliJ IDEA 的快捷键大全,包含了编辑、导航、重构、运行等多个方面的快捷键。请注意,这些快捷键是基于 Windows 版本的 Int…

Rust:启动与关闭线程

在 Rust 编程中,启动和关闭线程是并发编程的重要部分。Rust 提供了强大的线程支持,允许你轻松地创建和管理线程。下面将详细解释如何在 Rust 中启动和关闭线程。 启动线程 在 Rust 中,你可以使用标准库中的 std::thread 模块来创建和启动新…

从“点”到“面”,热成像防爆手机如何为安全织就“透视网”?

市场上测温产品让人眼花缭乱,通过调研分析,小编发现测温枪占很高比重。但是,测温枪局限于显示单一数值信息,无法直观地展示物体的整体温度分布情况,而且几乎没有功能拓展能力。以AORO A23为代表的热成像防爆手机改变了…

模型训练中GPU利用率低?

买了块魔改华硕猛禽2080ti,找了下没找到什么测试显存的软件,于是用训练模型来测试魔改后的显存稳定性,因为模型训练器没有资源监测,于是用了Windows任务管理器来查看显卡使用情况,却发现GPU的利用率怎么这么低&#xf…

开源代码管理平台Gitlab如何本地化部署并实现公网环境远程访问私有仓库

文章目录 前言1. 下载Gitlab2. 安装Gitlab3. 启动Gitlab4. 安装cpolar5. 创建隧道配置访问地址6. 固定GitLab访问地址6.1 保留二级子域名6.2 配置二级子域名 7. 测试访问二级子域名 前言 本文主要介绍如何在Linux CentOS8 中搭建GitLab私有仓库并且结合内网穿透工具实现在公网…

在vue3的vite网络请求报错 [vite] http proxy error:

在开发的过程中 代理proxy报错: [vite] http proxy error: /ranking/hostRank?dateType1 Error: connect ETIMEDOUT 43.xxx.xxx.xxx:443 网络请求是http的: // vite.config.ts import { Agent } from node:http;server: {host: 0.0.0.0,port: port,open: true,https: false,…

组合AC c++

题目描述 老师获得了一行字符串,想知道在不改变字符顺序的情况下,从前到后最多能组合出多少个ac? (a和c的位置可以不连续) 比如:字符串为addcadcc,可以找到5个ac,即下标组合为(0,3)、(0,6)、(0&#xff…

云计算 esxi 如何 部署iscsi ,配合windows 2012 iscsi 存储

1 windows 2012 如何创建iscsi 存储服务器,看前面的文章 iscsi 服务上的地址 192.168.10.196 192.168.10.196 2 如何在esxi 创建iscsi 注意地址是192.168.10.196 这是服务器的地址 很明显这是我们esxi 主机上发现的iscsi 磁盘 、