V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
unadlib
V2EX  ›  程序员

Mutative - 比 Immer 快 10 倍

  •  
  •   unadlib · 2023-01-29 10:33:38 +08:00 · 1495 次点击
    这是一个创建于 670 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Mutative - 一个用于高效的 immutable 数据更新的 JavaScript 库,默认情况下比 Immer 快 10 倍,甚至比 reducer 更快。

    动机

    手写 immutable 数据的更新通常很麻烦且容易出错的。Immer 帮助我们用"突变"逻辑编写更简单的 immutable 更新。

    但是它的性能问题导致了运行时的额外性能开销。Immer 默认情况下必须启用自动冻结功能(如果禁用自动冻结功能,性能会变得特别差),这使得 Immer 的 immutable 状态并不够通用。在跨进程、远程数据传输等场景下,我们必须不断冻结这些 immutable 数据。

    还有更多可以改进的部分,比如更好的类型推导、非侵入式标记、支持更多类型的 immutability 、更安全的 immutability ,等等。

    这就是创建 Mutative 的原因。

    Repo: https://github.com/unadlib/mutative

    Mutative vs Immer 性能

    测量( ops/sec )更新 50K 数组和 1K 对象的性能,越大越好(查看源码). [Mutative v0.3.2 vs Immer v9.0.18]

    Naive handcrafted reducer - No Freeze x 3,713 ops/sec ±0.86% (89 runs sampled)
    Mutative - No Freeze x 5,323 ops/sec ±1.69% (93 runs sampled)
    Immer - No Freeze x 8 ops/sec ±0.88% (23 runs sampled)
    
    Mutative - Freeze x 875 ops/sec ±1.20% (95 runs sampled)
    Immer - Freeze x 320 ops/sec ±0.45% (92 runs sampled)
    
    Mutative - Patches and No Freeze x 752 ops/sec ±0.16% (96 runs sampled)
    Immer - Patches and No Freeze x 7 ops/sec ±1.32% (23 runs sampled)
    
    Mutative - Patches and Freeze x 425 ops/sec ±0.33% (95 runs sampled)
    Immer - Patches and Freeze x 239 ops/sec ±0.99% (89 runs sampled)
    
    The fastest method is Mutative - No Freeze
    

    运行yarn benchmark来在本地重现这些基准测试数据。

    OS: macOS 12.6, CPU: Apple M1 Max, Node.js: 16.14.2

    Immer 依赖于自动冻结的启用,如果自动冻结被禁用,Immer 将有巨大的性能下降,而 Mutative 将有巨大的性能领先,特别是对于大数据结构,它将有超过 50 倍的性能领先。

    因此,如果你使用 Immer ,你将不得不启用自动冻结以提高性能。Mutative 默认允许禁用自动冻结。在两者的默认配置下,我们可以看到 Mutative (5,323 ops/sec)和 Immer (320 ops/sec)之间的明显性能差距。

    总的来说,在更多的性能测试场景中,Mutative 比 Immer 有着巨大的性能领先。运行yarn performance可以在本地获得所有的性能测试结果。

    特性和优点

    • Mutation makes immutable updates
    • Support apply patches
    • Optional freezing state
    • Custom shallow copy
    • Immutable and mutable data markable
    • Strict mode for safer mutable data access
    • Support for JSON patches
    • Support for reducer

    Mutative 和 Immer 的区别

    - Mutative Immer
    Custom shallow copy
    Strict mode
    No data freeze by default
    Non-invasive marking
    Complete freeze data
    Non-global config
    Support IE browser

    与 Immer 相比,Mutative 有更少的错误,如意外的草稿逃逸等等,查看详情

    Gzip 压缩后的 Mutative 大小为4.16KB。具有相同功能的 Immer 大小为4.67KB

    安装

    yarn add mutative # npm install mutative
    

    使用

    import { create } from "mutative";
    
    const baseState = {
      foo: "bar",
      list: [{ text: "coding" }],
    };
    
    const state = create(baseState, (draft) => {
      draft.foo = "foobar";
      draft.list.push({ text: "learning" });
    });
    

    create(baseState, (draft) => void, options?: Options): newState

    create()的第一个参数是基本状态。Mutative 将其起草并传递给 draft 函数的参数,并执行 draft 突变,直到 draft 函数执行结束,然后 Mutative 将最终定稿状态并产生新的状态。

    通过设置选项,使用create()实现更多的高级功能,它也支持 currying 。

    • strict - boolean, 默认为 false 。

      禁止在严格模式下访问不可起草的值。

    • enablePatches - boolean, 默认为 false 。

      启用 Patches ,并返回 Patches 和 inversePatches 。

    • enableAutoFreeze - boolean, 默认为 false 。

      启用自动冻结,并返回冻结状态。

    • mark - () => ('mutable'|'immutable'|function)

      设置一个标记来确定对象是否是可变的,或者一个实例是否是不可变的,它还可以返回一个浅层拷贝函数( AutoFreeze 和 Patches 都应该被禁用)。

    FAQs

    • 为什么 Mutative 不支持 IE ?

    Mutative 是一个在很大程度上依赖于使用 Proxy 对象的库,Proxy 对象是现代网络浏览器的一个重要功能,允许对对象的各种操作进行拦截。因此,Mutative 可能不完全兼容不支持 Proxy 对象的老式浏览器,如 Internet Explorer 。然而,这些旧的浏览器在整个浏览器市场中只占很小的比例,所以对兼容性的影响可能是最小的。

    • 为什么 Mutative 有这么好的性能表现?

    Mutative 优化的重点是浅拷贝优化、更完整的懒草稿、定稿过程优化等等。

    • 我已经在使用 Immer ,我可以平滑地迁移到 Mutative 吗?

    是的。除非你必须与 Internet Explorer 兼容,否则 Mutative 几乎支持 Immer 的所有功能,而且你可以轻松地从 Immer 迁移到 Mutative 。

    小结

    Mutative 的灵感来自 Immer 。Mutative 的目标是高效的 immutable 更新,专注于性能改进和更好的 API ,带来更好的开发体验。2018 年,Immer 被创建,但到了 2022-2023 年,我们需要一个性能更好的 immutable 更新的库来帮助我们提高应用性能。

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1531 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 17:08 · PVG 01:08 · LAX 09:08 · JFK 12:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.