掌握聚合最新动态了解行业最新趋势
API接口,开发服务,免费咨询服务

为什么用Immutable.js代替普通js对象?

本文由miaoyu 在众成翻译平台上翻译。

将数据视为不可变,将给你带来很多好处。事实上,这是也React背后的原理:React的元素是不可变的。

但是用Immutable.js有什么好处呢?


首先有一个非常巨大的对象…

这里有100,000条待办事项:

var todos = {
  ⋮
  t79444dae: { title: 'Task 50001', completed: false },
  t7eaf70c3: { title: 'Task 50002', completed: false },
  t2fd2ffa0: { title: 'Task 50003', completed: false },
  t6321775c: { title: 'Task 50004', completed: false },
  t2148bf88: { title: 'Task 50005', completed: false },
  t9e37b9b6: { title: 'Task 50006', completed: false },
  tb5b1b6ae: { title: 'Task 50007', completed: false },
  tfe88b26d: { title: 'Task 50008', completed: false },
  ⋮
  (100,000 items)
}

我要把第50,005条任务的completed改为ture。


用普通的JavaScript对象

function toggleTodo (todos, id) {
  return Object.assign({ }, todos, {
    [id]: Object.assign({ }, todos[id], {
      completed: !todos[id].completed
    })
  })
}

var nextState = toggleTodo(todos, 't2148bf88')

这项操作运行了134ms。

为什么用了这么长时间呢?因为当使用Object.assign,JavaScript会从旧对象(浅)复制每个属性到新的对象。

我们有100,000条待办事项,所以意味着有100,000个属性需要被(浅)复制。

这就是为什么花了这么长时间的原因。

在JavaScript中,对象默认是可变的。

当你复制一个对象时,JavaScript不得不复制每一个属性来保证这两个对象相互独立。

100,000个属性被(浅)复制到新的对象。


使用Immutable.js


var todos = Immutable.fromJS({
  ⋮
  t79444dae: { title: 'Task 50001', completed: false },
  t7eaf70c3: { title: 'Task 50002', completed: false },
  t2fd2ffa0: { title: 'Task 50003', completed: false },
  t6321775c: { title: 'Task 50004', completed: false },
  t2148bf88: { title: 'Task 50005', completed: false },
  t9e37b9b6: { title: 'Task 50006', completed: false },
  tb5b1b6ae: { title: 'Task 50007', completed: false },
  tfe88b26d: { title: 'Task 50008', completed: false },
  ⋮
  (100,000 items)
})

// 使用[updeep](https://github.com/substantial/updeep)
function toggleTodo (todos, id) {
  return u({
    [id]: {
      completed: (completed) => !completed
    }
  }, todos)
}

var nextState = toggleTodo(todos, 't2148bf88')

这项操作运行了1.2ms。速度提升了100倍。

为什么会这么快呢?


可持久化的数据结构

可持久化的数据结构强制约束所有的操作将返回新版本数据结构并且保持原有的数据结构不变,而不是直接修改原来的数据结构。

这意味着所有的可持久化数据结构是不可变的。

鉴于这个约束,第三方库在应用可持久化数据结构后可以更好的优化性能。


性能提升

为了直观的观察,让我们尝试一个小小例子。

键值对映射数据:

我们可以用一个普通的JavaScript对象来保存:

const data = {
  to: 7,
  tea: 3,
  ted: 4,
  ten: 12,
  A: 15,
  i: 11,
  in: 5,
  inn: 9
}

转换成一棵数据树,像这样:

图片来源: 维基百科

通常来讲,你可以从根节点沿着上图的路径来获取你想要的值。

如果你想获取data.in,从根节点开始,沿着i,n,就可以到达值为5的节点。

如何去修改呢?

比如我们想把键为tea的值3改成14。

我要建造一个新的树,并且尽可能重用已经存在的节点

绿色表示新建的节点。

灰色的节点失去的索引,将会被回收

正如你所看到的,我们只是重新创建了4个新的节点来更新这个树。其他节点都被重用了。

这叫 结构共享

Immutable.js就是通过这种方式实现Immutable.Map。创建一个树,每个节点最多有32个分支。

这张图展示了一个真实的Immutable.Map

当我们更新一个节点,只有几个节点需要被重新创建。

Immutable.js通过创建多种类型的节点来保持树结构的紧凑和性能:


万物皆有两面性...

请不要认为这篇文章的意思是“你应该经常使用Immutable.js。”,准确的讲,我只是告诉你用它的所有好处,以及为什么要使用它。

当我在写代码的时候,我首先会用普通的JavaScript对象和数组,当我使用Immutable.js时,我需要非常确定,比如一个对象包含10,000个属性。我几乎从不使用Immutable.js,因为大多数时候的对象都很小。

原文来自:众成翻译

声明:所有来源为“聚合数据”的内容信息,未经本网许可,不得转载!如对内容有异议或投诉,请与我们联系。邮箱:marketing@think-land.com

  • AI文本审核服务

    基于大模型能力构建的文本审核服务,能够高效精准地识别各类文本违规内容。与传统文本内容安全审核方案相比,具备更强大的语言理解与分析能力,能精准识别复杂、隐晦的违规内容,突破了传统模式的局限。

    基于大模型能力构建的文本审核服务,能够高效精准地识别各类文本违规内容。与传统文本内容安全审核方案相比,具备更强大的语言理解与分析能力,能精准识别复杂、隐晦的违规内容,突破了传统模式的局限。

  • AI图片审核服务

    基于图片审核大模型服务,能够全方位识别图片中的色情、性感、涉政、暴恐、违禁、宗教、引流广告、不良等违规内容,并支持返回大模型的审核结果。结合大模型和专家小模型,提供更细粒度的标签(如色情细分、具体行为、特定物体等),识别范围更广、标签更丰富。 综合效果最佳,适合对误判率、漏判率都有较高要求的场景。

    基于图片审核大模型服务,能够全方位识别图片中的色情、性感、涉政、暴恐、违禁、宗教、引流广告、不良等违规内容,并支持返回大模型的审核结果。结合大模型和专家小模型,提供更细粒度的标签(如色情细分、具体行为、特定物体等),识别范围更广、标签更丰富。 综合效果最佳,适合对误判率、漏判率都有较高要求的场景。

  • AIGC图片风险检测

    针对AIGC场景,检测AIGC生成的图片是否存在违规或者不宜传播的内容。建议AIGC生成的图片都进行该项检测。

    针对AIGC场景,检测AIGC生成的图片是否存在违规或者不宜传播的内容。建议AIGC生成的图片都进行该项检测。

  • AI生成图片鉴别

    检测图片是否疑似由AI生成合成、图片是否含有AI生成合成隐式标识(如果有隐式标识时支持返回图片AIGC元数据信息)。

    检测图片是否疑似由AI生成合成、图片是否含有AI生成合成隐式标识(如果有隐式标识时支持返回图片AIGC元数据信息)。

  • 诈骗风险感知检测

    根据身份证/手机号进行核验号码是否有涉险诈骗风险。

    根据身份证/手机号进行核验号码是否有涉险诈骗风险。

0512-88869195
客服微信二维码

微信扫码,咨询客服

数 据 驱 动 未 来
Data Drives The Future