了缺 2019-06-28
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的数据。
如果抛开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
。
执行的示例图如下:
普通的做法存在一个问题:每个方法各做各的事,没有协调起来浪费了很多资源。
如果能先把要做的事,用小本本记下来