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

and*_*dig 2 php arrays spl json zend-framework

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

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

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

  1. 使用 SPLFixedArray
  2. 使用stringpack()

这两种方法都会处理数组存储内存问题,但在使用JSON进行编码时会失败.

我已经研究了实现JsonSerializable但是因为它强制用户返回结果,然后在Json中编码我回到了

public function jsonSerialize() {
    return $this->toArray();
}
Run Code Online (Sandbox Code Playgroud)

它有相同的记忆问题.

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

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

and*_*dig 5

在我的调查中,我研究了5种不同的方法,用于在内存中存储大型元组,在此总结其结果(以50k记录采样):

  1. 幼稚

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

    内存:18.5MB(巨大)
    时间:~100ms构建和转储阵列(Windows PC)

  2. SPL图书馆

    这种方法将所有内容存储在嵌套中SPLFixedArrays:SPLFixedArray[SPLFixedArray].Zend\Json\Encoder通过实现该toJson方法扩展了JSON导出.

    内存:15.5MB(仍然很大)
    时间:~1.3s,x10慢

  3. SPL图书馆

    类似于2,但不是内部SPLFixedArray使用来自PHP pack()函数的压缩字符串.

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

  4. SPL图书馆

    类似于2,但SPLFixedArray实际的元组不是内部,而是简单地写为根数组的顺序值.

    内存:3.25MB(再次更小)
    时间:~0.7s,只有x6慢 - 我们在这里有赢家吗?

  5. pack()

    类似于3,但SPLFixedArray使用PHP的pack()函数将所有内容打包成单个字符串.这显然需要了解各个阵列的固定,相同结构.

    内存:1.25MB(真的很小 - 只有原始内存的
    1/12 )时间:~1.7s,x16慢

结论

虽然(5)提供最佳的内存利用率,但它也非常慢.出于我的目的,我已经确定了(4)这约占原始内存消耗的20%但是 - 当考虑JSON编码时 - 也慢了5~6倍.可接受的妥协.