Immutable.js

ImmutableJs出现背景

JavaScript中的Plain Object,一般是以引用形式存在的可变数据(Mutable Data),这样设计的目的可能是为了节省CPU与内存的开销;每次进行对象修改时直接改变对象本身(changed in-place rather than return a new object)

一般mutable data进行数据操作时比较简单,但是当在一些大型复杂应用中使用mutable data时可能会导致数据无法溯源,因为很多地方都可以修改这个数据,导致难以调试与维护;

当我们的项目中仅在很少的地方用到Immutable Data时,我们一般可以通过shallowCopy与deepCopy来简单实现,但是会造成CPU与内存的浪费 (camsong)

因此,immutable.js应运而生

ImmutableJs 优点

  1. 避免Mutable data带来的难以数据回溯问题;
  2. 节省内存与CPU
  3. 并发安全(不用担心数据更改不一致问题)
  4. undo/redo,copy/Paste,时间旅行等功能(可以通过列表保留历史记录进行各种相关操作)
  5. 函数式编程(ImmutableJs的设计本身就是遵循函数式编程思想)

ImmutableJs实现机制

持久化数据结构(Persistent Data Structure)

这是ImmutableJs实现的根本

被修改时总是保持该对象的旧版本并返回一个新的版本;即旧版本仍然是可访问的;

参考 https://medium.com/@dtinth/immutable-js-persistent-data-structures-and-structural-sharing-6d163fbd73d2

所有操作总是返回数据结构的一个新版本并保持原始数据的完整性,而不是就地修改原始数据;

结构化共享(Structural Sharing)

由旧对象创建新对象时仅需要创建和修改部分需要更新的节点,其他节点复用旧对象的节点,因此可以更加高效和节省内存;

结构化共享ImmutableJs性能优化的一个重要手段

数据结构与性能优化

ImmutableJs的结构化共享实现是基于tries的,包括Hash Array Map triesvector tries

vector tries限制了节点长度为32,这是通过实验验证得出一个合理值,是对查找和更新的trade-off;
单层过长的节点有利于查找,但不利于更新;

使用数字分区(Digit Partition)位分区(Bit Partition)immutable.js采用位分区可以有效提升查找速度,但是是以空间为代价的;

同时为了提供空间利用率,使用HAMT(Hash array mapped trie)对树高和树宽进行了压缩处理;树高压缩采用了移除非必要节点的方式,节点内部压缩(树宽)压缩采用了Bitmap方式避免不必要的位置索引存储;

这里bitmap压缩仅对子节点数小于16的节点进行处理,因此可以看到Immutable.Map有三种节点类型:

  1. HashArrayMapNode
  2. BitmapIndexedNode
  3. ValueNode
why 32

是2的整数次幂,便于计算;同时,对查询和更新进行了trade-off

在这里插入图片描述


参考文献

  1. https://github.com/vivatoviva/Interview-Frontend-2020/issues/16
  2. https://github.com/ascoders/weekly/issues/14
  3. https://github.com/camsong/blog/issues/3
  4. https://medium.com/@dtinth/immutable-js-persistent-data-structures-and-structural-sharing-6d163fbd73d2
  5. https://hypirion.com/musings/understanding-persistent-vector-pt-1
  6. 深入探究Immutable.js的实现机制(一)
  7. 深入探究Immutable.js的实现机制(二)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Neil-

你们的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值