我的应用程序需要生成一个具有大对象的 jsondata
数组类型的属性。数组在收集数据库输出时需要保留在内存中,并且某些属性只有在数组完成后才能确定。
复杂性:数组是基于数字的,并且必须在 json 输出中出现,因此直接json_encode()
不是一个选择。
为了在像 RasPi 这样的低规格机器上实现这一点,我研究了减少内存消耗:
- Use
SPLFixedArray
- Use
string
and pack()
这两种方法都解决了数组存储内存问题,但在 JSON 编码时都失败了。
我已经研究过实施JsonSerializable
但由于它强制用户返回结果,然后将其编码为 Json 我又回到了
public function jsonSerialize() {
return $this->toArray();
}
具有相同的内存问题。
zendframework/Component_ZendJson
看起来很有希望,因为它寻找具有toJson()
方法提供自己的编码为string
代替object
.
我想知道是否有更好的选择,不会出现内存问题?
在我的调查中,我研究了 5 种在内存中存储大型元组数组的不同方法,这里总结了它们的结果(以 50k 条记录采样):
-
Naive
使用 json_encode 导出 json 非常简单array(array(), array())
内存:18.5MB(huge)
时间:构建和转储阵列约 100 毫秒 (Windows PC)
-
SPL库
这种方法将所有内容存储在嵌套中SPLFixedArrays
: SPLFixedArray[SPLFixedArray]
。 JSON 导出已完成扩展Zend\Json\Encoder
通过实施toJson
method.
内存:15.5MB(仍然很大)
时间:约 1.3 秒,慢 10 倍
-
SPL库
与2类似,但不是内部SPLFixedArray
使用 PHP 的打包字符串pack()
功能。
内存:3.5MB(小5倍)
时间:~1.3s,慢 10 倍 - 显然pack()
与嵌套数组同样慢。
-
SPL库
与2类似,但不是内部SPLFixedArray
实际的元组只是作为顺序值写入根数组。
内存:3.25MB(再次变小)
时间:约 0.7 秒,仅慢 6 倍 - 我们这里有赢家吗?
-
pack()
与3类似,但不是根SPLFixedArray
使用 PHP 将所有内容打包到一个字符串中pack()
功能。这显然需要有关各个阵列的知识和固定的、相同的结构。
内存:1.25MB(非常小 - 只有原始内存的 1/12)
时间:约 1.7 秒,慢 16 倍
结论
虽然 (5) 提供了最佳的内存利用率,但速度也非常慢。出于我的目的,我选择了 (4),它大约是原始内存消耗的 20%,但是,当考虑到 JSON 编码时,速度也会慢 5~6 倍。一个可以接受的妥协。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)