在像V8这样的JavaScript引擎中,对象是否比返回它的函数消耗更多的内存?

9udxz4iz  于 2023-05-05  发布在  Java
关注(0)|答案(1)|浏览(121)

假设我有一个非平凡的静态数据结构:

[
  { id: 1, title: 'Long title 1...' },
  { id: 2, title: 'Long title 2...' },
  /* 998 more... */
]

考虑到我的应用很少需要Map/过滤这个(我假设将模块保留在内存中),它是否会消耗更少的内存来(A)将其导出为常量:

export const rows = [ ... ];

或者(B),导出一个返回文字的函数:

export function getRows() {
  return [ ... ];
}

或者(C),导出一个JSON解析字符串文字的函数?

export function getRows() {
  return JSON.parse("[ ... ]");
}

需要明确的是,关注的是它在页面生命周期内对浏览器选项卡的RAM消耗的贡献。在不频繁的操作期间,RAM使用的瞬时峰值不太值得关注。
我知道在(B)和(C)中,每次调用都可能会导致一些对象构造时间,但这并不像占用RAM那样令人担忧。我知道(C)推迟了字面量的解析时间,但不清楚解析后的表示是否比JSON字符串字面量消耗更多的RAM。

63lcw9qa

63lcw9qa1#

从我执行的in this repo测试中,“赢家”是(C),长期内存消耗最少,(B)消耗两倍的内存,(A)4x 的内存。
当然,这将取决于数据的大小和形状。在这种情况下:
| 案例展示|模块导出|磁盘上的大小(B)|30秒后添加到“heapUsed”的字节数|
| --------------|--------------|--------------|--------------|
| C类|使用JSON.parse()的函数|一百四十万零六百六十七|一百九十三万四千三百三十六|
| B|返回文字的函数|一百三十七万九千八百四十五|四百四十二万二千六百五十六|
| 一个|常数|一百三十七万九千八百二十八|九○一万八千三百六十八|
每个模块都单独测试,首先捕获memoryUsage()的输出,然后动态加载数据模块,访问数据,然后在加载后等待10秒和30秒,然后重新测量内存使用情况(不允许导入的资源超出范围)。可以看到3次运行的结果为in this spreadsheet(这些值是从基线调用到memoryUsage()的增量,单位为kB)。
我怀疑的是,源代码中的单个大JSON字符串可以存储在连续的RAM中,而其他两种表示需要更多的单个对象和昂贵的“边缘”,因为缺乏更好的术语。令人惊讶的是,构造变量占用的内存是返回文本对象的函数的编译表示的两倍!

相关问题