JavaScript 数组是否明显小于堆上的对象?

Are JavaScript Arrays significantly smaller than Objects on the heap?

我正在浏览器中处理(网络)图表,想知道是否可以通过更改表示它们的方式来显着减少内存使用量。

我正在考虑更改边的表示形式:

{from : string, to : string, weight : number, bi : boolean}

收件人:

[string, string, number, boolean]

我认识到这个特定用例的序列化 Object 大小和 Array 大小没有太大区别,尤其是当我缩短密钥时。但是,我很好奇大多数浏览器中堆上 ObjectsArrays 的大小是否存在显着差异。如果我最关心浏览器 运行 V8,有没有办法在 Node 中测试它?

注意:如果没有我的应用程序的图形部分,我的 JS 堆已经有点大了(我的逻辑 15 MB + 几帧 50 MB)。因此,尝试这样的事情有一些超出我好奇心的理由。

(此处为 V8 开发人员。)

我期望的是 object 比本例中的数组略小。我还希望差异仅在您有 很多 的 object 时才重要。

原因是 V8 的“隐藏 类”系统,其中属性名称只存储一次并由具有相同“形状”的所有 object 共享,因此每个 object 需要 3 个指针 (object header) + 4 个属性指针,每个指针为 4 个字节,总共 7*4 = 28 个字节。 属性 名称的长度不影响 per-object 内存要求。数组多了一个属性(.length),它们的元素会存储在单独的backing store中,所以每个数组的总内存消耗应该是3(object header) + 1(长度)+ 2(后备存储 header)+ 4(元素)指针 = 10 个指针或 40 个字节。

在更简单的 JavaScript 引擎中,所有 object 都作为字典实现,数组确实可以节省一些内存,因为每个 object 都会存储 属性 名称,至少作为指向共享字符串的指针——当然,除非数组在这样的引擎中也被实现为字典,在这种情况下,它们会再次变大一点,因为它们有额外的 length 属性.
根据您对 object 所做的其他操作,您可以让 V8 将它们迁移到字典模式(因为隐藏 类 有很多好处,在某些情况下也有一些缺点),但您更有可能都会遇到上述情况。

因此,对于性能和内存问题,唯一可以确定的方法是 在您的真实应用中(而不是在简化的微基准测试中) 实施这两种方法并测量影响。如果您无法衡量差异,则无需担心差异。