变异对象与浅克隆的性能



我喜欢函数式编程范式,根据我的说法,它能产生更干净、更容易理解的代码,但我想知道性能损失是否有意义。

让我们以一个向对象添加新属性的函数为例。一种非功能性方法如下:

const addProp = (obj, prop, val) => {
obj[prop] = val; // Mutate the object
return obj;
}

而功能方法看起来是这样的:

const addProp = (obj, prop, val) => ({ ...obj, [prop]: val }); // Shallow clone

与对象突变相比,浅层克隆的成本是多少?我想知道函数式编程模式会在多大程度上降低性能(如果确实如此的话(。

制作浅拷贝的性能比突变的性能差得多。如果我有一个有400个元素的数组,并且我做了一个浅拷贝,那么这将比破坏性地修改数组中的单个元素要贵得多。阵列越长,间隙就越差。具有许多属性的对象也会出现同样的问题。

高效函数编程的一个基本要素是使用正确的数据结构。在这种情况下,您需要一个数据结构,其中修改部分数据结构并不意味着您必须完全重新创建数据结构。您希望数据结构的本地修改能够与原始结构共享其大部分内存。

一个非常基本的例子是一个单独链接的列表。如果希望在链表中预先添加单个元素,这是一个O(1)操作,因为新列表与旧列表共享大部分内存。但是,在不改变原始数组的情况下向数组中添加单个元素是一种线性时间操作,因为必须复制整个数组。

对于序列和映射,通常使用某种平衡树。函数式编程语言将这些数据结构作为其标准库的一部分,但我相信有人已经为函数式Javascript编写了一个库。