前言

lodash受欢迎的一个原因,是其优异的计算性能。而其性能能有这么突出的表现,很大部分就来源于其使用的算法——惰性求值。

本文将讲述lodash源码中,惰性求值的原理和实现。

一、惰性求值的原理分析

惰性求值(Lazy Evaluation),又译为惰性计算、懒惰求值,也称为传需求调用(call-by-need),是计算机编程中的一个概念,它的目的是要最小化计算机要做的工作

惰性求值中的参数直到需要时才会进行计算。这种程序实际上是从末尾开始反向执行的。它会判断自己需要返回什么,并继续向后执行来确定要这样做需要哪些值。

以下是How to Speed Up Lo-Dash ×100? Introducing Lazy Evaluation.(如何提升Lo-Dash百倍算力?惰性计算的简介)文中的示例,形象地展示惰性求值。

function priceLt(x) {
return function(item) { return item.price < x; };
}
var gems = [
{ name: 'Sunstone', price: 4 },
{ name: 'Amethyst', price: 15 },
{ name: 'Prehnite', price: 20},
{ name: 'Sugilite', price: 7 },
{ name: 'Diopside', price: 3 },
{ name: 'Feldspar', price: 13 },
{ name: 'Dioptase', price: 2 },
{ name: 'Sapphire', price: 20 }
]; var chosen = _(gems).filter(priceLt(10)).take(3).value();

程序的目的,是对数据集gems进行筛选,选出3个price小于10的数据。

1.1 一般的做法

如果抛开lodash这个工具库,让你用普通的方式实现var chosen = _(gems).filter(priceLt(10)).take(3);那么,可以用以下方式:

_(gems)拿到数据集,缓存起来。

再执行filter方法,遍历gems数组(长度为10),取出符合条件的数据:

[
{ name: 'Sunstone', price: 4 },
{ name: 'Sugilite', price: 7 },
{ name: 'Diopside', price: 3 },
{ name: 'Dioptase', price: 2 }
]

然后,执行take方法,提取前3个数据。

[
{ name: 'Sunstone', price: 4 },
{ name: 'Sugilite', price: 7 },
{ name: 'Diopside', price: 3 }
]

总共遍历的次数为:10+3

执行的示例图如下:

1.2 惰性求值做法

普通的做法存在一个问题:每个方法各做各的事,没有协调起来浪费了很多资源。

如果能先把要做的事,用小本本记下来

惰性求值——lodash源码解读的更多相关文章

  1. ThreadLocal源码解读

    1. 背景 ThreadLocal源码解读,网上面早已经泛滥了,大多比较浅,甚至有的连基本原理都说的很有问题,包括百度搜索出来的第一篇高访问量博文,说ThreadLocal内部有个map,键为线程对象 ...

  2. lodash源码分析之NaN不是NaN

    暗恋之纯粹,在于不求结果,完全把自己锁闭在一个单向的关系里面. --梁文道<暗恋到偷窥> 本文为读 lodash 源码的第五篇,后续文章会更新到这个仓库中,欢迎 star:pocket-l ...

  3. Webpack探索【16】--- 懒加载构建原理详解(模块如何被组建&如何加载)&源码解读

    本文主要说明Webpack懒加载构建和加载的原理,对构建后的源码进行分析. 一 说明 本文以一个简单的示例,通过对构建好的bundle.js源码进行分析,说明Webpack懒加载构建原理. 本文使用的 ...

  4. Webpack探索【15】--- 基础构建原理详解(模块如何被组建&如何加载)&源码解读

    本文主要说明Webpack模块构建和加载的原理,对构建后的源码进行分析. 一 说明 本文以一个简单的示例,通过对构建好的bundle.js源码进行分析,说明Webpack的基础构建原理. 本文使用的W ...

  5. go 中 sort 如何排序,源码解读

    sort 包源码解读 前言 如何使用 基本数据类型切片的排序 自定义 Less 排序比较器 自定义数据结构的排序 分析下源码 不稳定排序 稳定排序 查找 Interface 总结 参考 sort 包源 ...

  6. CesiumJS 2022^ 源码解读[7] - 3DTiles 的请求、加载处理流程解析

    目录 1. 3DTiles 数据集的类型 2. 创建瓦片树 2.1. 请求入口文件 2.2. 创建树结构 2.3. 瓦片缓存机制带来的能力 3. 瓦片树的遍历更新 3.1. 三个大步骤 3.2. 遍历 ...

  7. SDWebImage源码解读之SDWebImageDownloaderOperation

    第七篇 前言 本篇文章主要讲解下载操作的相关知识,SDWebImageDownloaderOperation的主要任务是把一张图片从服务器下载到内存中.下载数据并不难,如何对下载这一系列的任务进行设计 ...

  8. SDWebImage源码解读 之 UIImage+GIF

    第二篇 前言 本篇是和GIF相关的一个UIImage的分类.主要提供了三个方法: + (UIImage *)sd_animatedGIFNamed:(NSString *)name ----- 根据名 ...

  9. SDWebImage源码解读_之SDWebImageDecoder

    第四篇 前言 首先,我们要弄明白一个问题? 为什么要对UIImage进行解码呢?难道不能直接使用吗? 其实不解码也是可以使用的,假如说我们通过imageNamed:来加载image,系统默认会在主线程 ...

随机推荐

  1. npm link 命令解析

    文字转的 对开发者而言,这算是最有价值的命令.假设我们开发了一个模块叫 test ,然后我们在 test-example 里引用这个模块 ,每次 test 模块的变动我们都需要反映到 test-exa ...

  2. [译].NET Framework 4.8发布

    原文地址:https://devblogs.microsoft.com/dotnet/announcing-the-net-framework-4-8/ 我们很高兴地宣布今天发布.NET Framew ...

  3. vue-06-过度和动画

    1, css过度与动画 需要使用 v-if, v-show 来进行 1), 过度类名 v-enter: 进入时触发 v-enter-active: 执行过程中 v-enter-to: 停止时进行 v- ...

  4. leetcode — spiral-matrix-ii

    import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Source : https://o ...

  5. LeetCode Animation 题目图解汇总(持续更新中...)

    我会尽力将LeetCode上所有的题目都用动画的形式演示出来,期待与你见证这一天! GitHub Repo:LeetCode Animation Follow: MisterBooo · GitHub ...

  6. anoconda包管理汇总

    anoconda默认的seaborn版本是0.8.1 seaborn的最新版本是0.9.0  并且已经没有0.8.1的文档了. 升级anoconda的seaborn版本 进入anoconda prom ...

  7. 关于div容器在ie6下默认高度不为0(存在默认高度)

    最近做项目的时候遇到一个问题,相信很多人都遇到过,就是在测试兼容性的时候,在ie6下小于12px 的背景的高度不等于原高,或许这样说你可能不是很明白,那就举个例子吧! 如图所示: 锯齿状的背景图本来是 ...

  8. PHP 科学计数 转 Double

    本文转自:https://stackoverflow.com/questions/4576927/convert-a-string-containing-a-number-in-scientific- ...

  9. .net敏捷开发框架 力软敏捷开发(learun) 让开发变的更简单

    版本:6.1.6.2 体验地址:www.fishcmonkey.com 联系QQ:6539471

  10. Java基础篇——JVM之GC原理(干货满满)

    原创不易,如需转载,请注明出处https://www.cnblogs.com/baixianlong/p/10697554.html ,多多支持哈! 一.什么是GC? GC是垃圾收集的意思,内存处理是 ...