如何将大型对象/数组序列化为 JSON

2024-03-27

我的应用程序需要生成一个具有大对象的 jsondata数组类型的属性。数组在收集数据库输出时需要保留在内存中,并且某些属性只有在数组完成后才能确定。

复杂性:数组是基于数字的,并且必须在 json 输出中出现,因此直接json_encode()不是一个选择。

为了在像 RasPi 这样的低规格机器上实现这一点,我研究了减少内存消耗:

  1. Use SPLFixedArray
  2. Use string and pack()

这两种方法都解决了数组存储内存问题,但在 JSON 编码时都失败了。

我已经研究过实施JsonSerializable但由于它强制用户返回结果,然后将其编码为 Json 我又回到了

public function jsonSerialize() {
    return $this->toArray();
}

具有相同的内存问题。

zendframework/Component_ZendJson看起来很有希望,因为它寻找具有toJson()方法提供自己的编码为string代替object.

我想知道是否有更好的选择,不会出现内存问题?


在我的调查中,我研究了 5 种在内存中存储大型元组数组的不同方法,这里总结了它们的结果(以 50k 条记录采样):

  1. Naive

    使用 json_encode 导出 json 非常简单array(array(), array())

    内存:18.5MB(huge)
    时间:构建和转储阵列约 100 毫秒 (Windows PC)

  2. SPL库

    这种方法将所有内容存储在嵌套中SPLFixedArrays: SPLFixedArray[SPLFixedArray]。 JSON 导出已完成扩展Zend\Json\Encoder通过实施toJson method.

    内存:15.5MB(仍然很大)
    时间:约 1.3 秒,慢 10 倍

  3. SPL库

    与2类似,但不是内部SPLFixedArray使用 PHP 的打包字符串pack()功能。

    内存:3.5MB(小5倍)
    时间:~1.3s,慢 10 倍 - 显然pack()与嵌套数组同样慢。

  4. SPL库

    与2类似,但不是内部SPLFixedArray实际的元组只是作为顺序值写入根数组。

    内存:3.25MB(再次变小)
    时间:约 0.7 秒,仅慢 6 倍 - 我们这里有赢家吗?

  5. pack()

    与3类似,但不是根SPLFixedArray使用 PHP 将所有内容打包到一个字符串中pack()功能。这显然需要有关各个阵列的知识和固定的、相同的结构。

    内存:1.25MB(非常小 - 只有原始内存的 1/12)
    时间:约 1.7 秒,慢 16 倍

结论

虽然 (5) 提供了最佳的内存利用率,但速度也非常慢。出于我的目的,我选择了 (4),它大约是原始内存消耗的 20%,但是,当考虑到 JSON 编码时,速度也会慢 5~6 倍。一个可以接受的妥协。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将大型对象/数组序列化为 JSON 的相关文章

随机推荐

  • 安卓用C++还是Java?

    我正在考虑在空闲时间学习 Android 开发 我发现 Java 和 C 都可以进行开发 但后者是有限的 我对 C 更加满意 所以我的问题是 Android 上的 C 存在哪些限制 我能够用它开发完整的应用程序吗 还是我最终必须学习 Jav
  • C 中数组的理想数据类型

    我想存储键和可变大小数组之间的静态关联 foo gt bar awe foo2 gt bar2 awe2 gruh 该数组在程序执行期间永远不会改变 它只是将字符串变量数组与字符串键静态关联的一种方法 子阵列的数量非常少 我怎样才能纯粹地做
  • 等待 .forEach() 完成的最佳方法

    有时我需要等待 forEach 方法来完成 主要是 加载器 功能 这就是我这样做的方式 q when array forEach function item iterate on something then function contin
  • Google 地图 v3 折线工具提示

    谷歌地图标记对象 google maps Marker 有一个 title 属性 因此当用户将鼠标移到标记上时 会显示一个简单的工具提示 折线 google maps Polyline 上没有标题属性 有没有办法可以在 V3 中做到这一点
  • 如何使用谷歌脚本打开位于谷歌驱动器文件夹中的Excel文件?

    我需要打开给定的谷歌驱动器文件夹中的 Excel 文件并读取其数据 为此 我使用了以下代码 var folders DriveApp getFoldersByName Test Folder var foldersnext folders
  • 结构或联合中的“unsigned temp:3”是什么意思? [复制]

    这个问题在这里已经有答案了 可能的重复 这段C 代码是什么意思 https stackoverflow com questions 1604968 what does this c code mean 我正在尝试使用 JNA 将 C 结构映
  • 根据两者的坐标选择某个位置的设备并对其进行计数

    通过使用 SQL 地理的 STContains 函数 可以计算一组坐标是否在一个区域内 https stackoverflow com questions 64453530 match location between coordinate
  • str.split() 返回的 Pandas 排序列表

    给定 str 类型的 Pandas Series 我想对 str split 返回的结果进行排序 例如 给定系列 s pd Series abc def ghi ghi abc 我想得到 s2 pd Series abc def ghi a
  • 如何监听 Flutter 中 platformBrightness 的变化?

    我正在设置一个系统 当用户将系统主题更改为深色模式时 它会更改主题 并且使用 Flutter 它运行得很好 但是 当用户更改系统主题时 系统导航和状态栏不会改变其颜色 我在构建方法内的主页上运行了代码 但这似乎没有做到这一点 这是主页构建方
  • jQuery Panzoom 插件将图像定位在右侧,包含:'invert'

    我正在尝试使用jQuery 全景缩放 https github com timmywil jquery panzoom插件 基本上都很好 除了 我希望最初缩放大图像以适合容器 并且有contain invert 已启用 我已经适应了这个例子
  • Windows 批处理:杀死进程

    我正在运行多个具有相同名称的进程 我希望有一个选项可以从批处理脚本中杀死它们 我需要一些与 unix shell 命令非常相似的东西 kill 9 ps axuw grep MY PROCESS NAME awk print 2 有什么建议
  • 使用 OperatorPrecedenceParser 通过 FParsec 解析函数应用程序?

    问题类似于this one https stackoverflow com questions 7199589 parsing method arguments with fparsec 但我想使用函数应用程序来解析表达式OperatorP
  • Laravel 5 无限滚动 + 分页

    对于在 l5 中使用 paginate 进行无限滚动 我发现了很多文章 但它们都使用这个 paginate 函数 因为它们使用来自 db 的结果集 但我从 googlefontapi 获取数据作为 json 所以当我在 json 中使用 p
  • 如何在 SQL 中查找去年的同一个工作日?

    通常在销售报告等中 您需要将这一天与去年的同一天进行比较 但基于相同的 工作日 而不是 每月的某一天 例如 今天是 2013 年 6 月 20 日 星期四 我希望看到今天的销售额与去年同一个星期四的销售额 2012 年 6 月 21 日 而
  • 如何抑制由我​​无法更改的代码显示的对话框?

    我有一个来自第 3 方的 Inproc COM 服务器 我调用的函数之一如果捕获特定类型的错误 将显示错误消息对话框 问题是我正在尝试批量处理数据 而我正在使用的数据源导致错误对话框频繁弹出 如果它产生 1000 个对话框 这不会成为问题
  • javascript 内联有什么好的理由吗

    我一直在建立一个网站 在某个阶段 我注意到 IE 显示有点损坏 Chrome 几乎除了 body 标签 空 之外什么都没有渲染 而 FF 看起来都不错 在把键盘扔到房间里并用头撞鼠标后 我发现了问题 我在内联脚本块中留下了未关闭的 HTML
  • 运行 kubectl exec 时禁用 Kubernetes 上的网络日志

    跑步kubectl exec it
  • Oracle - 返回新插入的键值

    我们有一个带有主键的表 该表在插入时由表上的触发器填充 触发器从我们为表创建的序列中获取下一个序列号 并将其用作插入时键的值 现在我们希望能够在插入过程 PL SQL 中返回该值 类似于 SQL Server 中的 select scope
  • 为什么 .gitconfig [includeIf] 不起作用?

    系统设置 MacOS Catalina 10 15 6 gt git version git version 2 24 3 Apple Git 128 file gitconfig user name nickname email emai
  • 如何将大型对象/数组序列化为 JSON

    我的应用程序需要生成一个具有大对象的 jsondata数组类型的属性 数组在收集数据库输出时需要保留在内存中 并且某些属性只有在数组完成后才能确定 复杂性 数组是基于数字的 并且必须在 json 输出中出现 因此直接json encode