使用immutable.js覆盖Object.assign或spread运算符的优点

到目前为止,大部分“初学者样板”和一些关于react / redux的帖子我都看到鼓励使用immutable.js来解决可变性问题。 我个人依赖Object.assign或传播运算符来处理这个问题,因此在immutable.js中并没有真正看到优势,因为它增加了额外的学习,并且从用于可变性的vanilla js技术转移了一点。 我试图找到一个切换的正确理由,但无法因此我在这里问,看看它为什么如此受欢迎。


这是关于效率。

持久数据结构

持久数据结构通过始终产生新的数据结构来改变其自身的先前版本。 为了避免昂贵的克隆,只存储与之前数据结构的差异,而交叉点在它们之间共享。 这种策略被称为结构共享。 因此,使用Object.assign或spread操作符来克隆持久数据结构要高效得多。

Javascript中持久数据结构的缺点

不幸的是,Javascript本身不支持持久数据结构。 这就是immutable.js存在的原因,并且它的对象与普通的旧的Javascript Object不同。 这导致更详细的代码和持久数据结构转换为本地Javascript数据结构。

关键的问题

immutable.js结构共享(效率)的好处何时超过其缺点(冗长,转换)?

我猜这个图书馆只有在拥有大量对象和集合的大型项目中才会有收益,因为克隆整个数据结构和垃圾回收会变得更加昂贵。


我为多个不可变库创建了性能基准,脚本和结果位于immutable-assign(GitHub项目)内部,这表明immutable.js针对写操作进行了优化,比Object.assign()快,但是,它读取操作速度较慢。 以下是基准测试结果的总结:

-- Mutable
Total elapsed = 50 ms (read) + 53 ms (write) = 103 ms.

-- Immutable (Object.assign)
Total elapsed = 50 ms (read) + 2149 ms (write) = 2199 ms.

-- Immutable (immutable.js)
Total elapsed = 638 ms (read) + 1052 ms (write) = 1690 ms.

-- Immutable (seamless-immutable)
Total elapsed = 31 ms (read) + 91302 ms (write) = 91333 ms.

-- Immutable (immutable-assign (created by me))
Total elapsed = 50 ms (read) + 2173 ms (write) = 2223 ms.

因此,是否使用immutable.js将取决于应用程序的类型,以及读写比。 如果你有很多写操作,那么immutable.js将是一个不错的选择。

不成熟的优化是万恶之源

理想情况下,您应该在介绍任何性能优化之前对应用程序进行简介,但是,不变性是必须尽早决定的设计决策之一。 当你开始使用immutable.js时,你需要在整个应用程序中使用它来获得性能优势,因为使用fromJS()和toJS()与普通的JS对象互操作是非常昂贵的。


我认为ImmutableJs的主要优势在于其数据结构和速度。 当然,它也强制不变,但你应该这样做,所以这只是一个额外的好处。

例如,假设你的reducer中有一个非常大的对象,并且你想改变该对象的一小部分。 由于不可变性,您不能直接更改对象,但必须创建对象的副本。 你通过复制所有东西(在ES6中使用扩展运算符)来做到这一点。

所以有什么问题? 复制非常大的对象非常慢。 ImmutableJS中的数据结构做一些叫做结构共享的事情,你只需要改变你想要的数据。 您没有更改的其他数据在对象之间共享,因此不会被复制。

这样做的结果是高效的数据结构,写入速度很快。

ImmutableJS还提供了深层对象的简单比较。 例如

const a = Immutable.Map({ a: Immutable.Map({ a: 'a', b: 'b'}), b: 'b'});
const b = Immutable.Map({ a: Immutable.Map({ a: 'a', b: 'b'}), b: 'b'});

console.log(a.equals(b)) // true 

如果没有这个,你需要某种深度比较函数,这也需要很多时间,而这里的根节点包含整个数据结构的散列(不要在此引用我,这是我如何记住它,但是比较总是即时的),所以比较总是O(1)即即时,而不管对象大小如何。

这可以在阵营特别有用shouldComponentUpdate方法,在这里你可以使用这个只是比较道具equals功能,它运行在瞬间完成。

当然,也有缺点,如果你将immutablejs结构和常规对象混合在一起,很难说出什么是什么。 此外,您的代码库中充斥着不同于普通Javascript的immutableJS语法。

另一个缺点是,如果你不打算使用深度嵌套对象,它将比普通的js慢一些,因为数据结构确实有一些开销。

只是我2美分。

链接地址: http://www.djcxy.com/p/39569.html

上一篇: Advantages of using immutable.js over Object.assign or spread operators

下一篇: Why is String.equalsIgnoreCase is so slow