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

我的应用程序需要生成具有大型 data </ code>属性的对象的json 阵列。 数组需要在收集数据库输出时保留在内存中,并且只有在数组完成后才能确定某些属性。 </ p>

复杂化:数组是基于数字的,并且必须在json输出中显示,因此直接 json_encode()</ code>不是一个选项。</ p>

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


  1. 使用 SPLFixedArray </ code> </ li>
  2. 使用 string </ code>和 pack()</ code> </ li>
    </ ol>

    两种方法 处理数组存储内存问题,但在JSON编码方面失败。</ p>

    我已经研究了实现 JsonSerializable </ code>但是因为它迫使用户返回 结果然后在Json中编码我回到</ p>

      public function jsonSerialize(){
    return $ this-&gt; toArray();
    }
    </ code> </ pre>

    具有相同的内存问题。</ p>

    zendframework / Component_ZendJson </ code>看起来很有前途 使用 toJson()</ code>方法提供自己的编码为 string </ code> object </ code>。</ p>

    我想知道是否有更好的选项不会给出内存问题?</ p>
    </ div>

展开原文

原文

My app needs to produce json of an object that has a large data property of type array. The array needs to remain in memory as it collects DB output and some properties can only be determined once the array is completed.

Complication: the array is numerically-based and must appear as such in the json output, therefore straight json_encode() is not an option.

To make this possible on low-spec machines like RasPi I've looked into trimming memory consumption:

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

Both approaches take care of the array storage memory problem but fail when it comes to encoding in JSON.

I've looked into implementing JsonSerializable but as it forces users to return the result which is then encoded in Json I'm back to

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

which has the same memory problems.

zendframework/Component_ZendJson looks promising as it looks for objects having a toJson() method to provide their own encoding as stringinstead of object.

I'm wondering if there are better options that don't give memory issues?

dp815292
dp815292 需要反过来强制它到阵列而不是对象。
6 年多之前 回复
duanqiao8925
duanqiao8925 这个?stackoverflow.com/a/4844309/46675
6 年多之前 回复
doq91130
doq91130 接得好。当然有理由我忘了提。游民。复杂:数组是基于数字的,并且必须在json输出中显示,因此直接json_encode()不是一个选项。
6 年多之前 回复
doubi6215
doubi6215 我确信你正在做的事情远远超出我的想象,但PHP本身就有json_encode。如果它不适用,那么我可以删除此评论=)
6 年多之前 回复

2个回答



在我的调查中,我研究了5种不同的方法,用于在内存中存储大型元组数组,这里总结了它们的结果(在 50k记录):</ p>


  1. Naive </ em> </ p>

    json_encode使用<导出json非常简单 code> array(array(),array())</ code> </ p>

    内存:18.5MB(巨大</ strong>)

    时间:~100ms到 构建和转储数组(Windows PC)</ p> </ li>

  2. SPL库</ em> </ p>

    此方法存储所有内容 嵌套 SPLFixedArrays </ code>: SPLFixedArray [SPLFixedArray] </ code>。 JSON导出通过实现 toJson </ code>方法扩展 Zend \ Json \ Encoder </ code>。</ p>

    内存:15.5MB(仍然 大</ strong>)

    时间:~1.3s,x10较慢</ p> </ li>

  3. SPL库</ p>

    类似于2 ,而不是内部 SPLFixedArray </ code>使用PHP的 pack()</ code>函数中的压缩字符串。</ p>

    内存:3.5MB( 5倍小</ strong>)

    时间:~1.3s,x10慢 - 显然 pack()</ code>与嵌套数组一样慢。</ p> </ li>
    < li>

    SPL库</ p>

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

    内存:3.25MB(再次更小</ strong>)

    时间:~0.7s,只有x6更慢 - 我们在这里有赢家吗?</ p> </ li>

  4. pack()</ code> </ p>

    与3类似,但不是根 SPLFixedArray </ code> 使用PHP的 pack()</ code> f将所有内容打包成一个字符串 结。 这显然需要知识和各个阵列的固定,相同的结构。</ p>

    内存:1.25MB(非常小 - 仅为原始内存的1/12 </ strong> )

    时间:~1.7s,x16较慢</ p> </ li>
    </ ol>

    结论</ strong> </ p>

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

展开原文

原文

In my investigation I've looked at 5 different approaches for storing large arrays of tuples in memory, summarized here with their results (sampled at 50k records):

  1. Naive

    Exporting json is straightforward with json_encode using array(array(), array())

    Memory: 18.5MB (huge)
    Time: ~100ms to build and dump the array (Windows PC)

  2. SPL Library

    This approach stores everything in nested SPLFixedArrays: SPLFixedArray[SPLFixedArray]. JSON export was done extending Zend\Json\Encoder by implementing the toJson method.

    Memory: 15.5MB (still large)
    Time: ~1.3s, x10 slower

  3. SPL Library

    Similar to 2, but instead of the inner SPLFixedArray uses packed strings from PHP's pack() function.

    Memory: 3.5MB (5 times smaller)
    Time: ~1.3s, x10 slower - apparently pack() is similarly slow as nested array.

  4. SPL Library

    Similar to 2, but instead of the inner SPLFixedArray the actual Tuples are simply written as sequential values to the root array.

    Memory: 3.25MB (again smaller)
    Time: ~0.7s, only x6 slower - do we have a winner here?

  5. pack()

    Similar to 3, but instead of the root SPLFixedArray pack everything into a single string using PHP's pack() function. This does obviously need knowledge about and a fixed, identical structure of the individual arrays.

    Memory: 1.25MB (really small - only 1/12th of original memory)
    Time: ~1.7s, x16 slower

CONCLUSION

While (5) offers best memory utilization it is also extremely slow. For my purposes I've settled on (4) which is about 20% of original memory consumption but- when JSON encoding is taken into account- also 5~6 times slower. An acceptable compromise.

dongwuxie7976
dongwuxie7976 可能的最佳和最全面的答案之一。
大约 5 年之前 回复



根据 json.org </ a>:</ p>


JSON构建于两种结构上:</ p>


  • 名称/的集合 价值对</ strong>。 在各种语言中,这被实现为对象</ strong>,记录,结构,字典,哈希表,键控列表或关联数组。</ li>
  • 已订购 值列表</ strong>。 在大多数语言中,这被实现为数组</ strong>,向量,列表或序列。</ li>
    </ ul>
    </ blockquote>


    我不知道是否存在内存问题,但请考虑以下代码:</ p>

     &lt;?php 
    //没有声明的索引导致no JSON中的索引
    $ arr = array('dssdf','38904uj');
    echo json_encode($ arr)。'&lt; br&gt;&lt; br&gt;';
    // [“dssdf”,“38904uj” ]

    //从0开始数组从JSON
    $ arr = array('0'=&gt;'dssdf','1'=&gt;'38904uj')删除索引;
    echo json_encode($ arr )。'&lt; br&gt;&lt; br&gt;';
    // [“dssdf”,“38904uj”]

    //在1开始数组强制索引显示在JSON
    $ arr = array( '1'=&gt;'dssdf','2'=&gt;'38904uj');
    echo json_encode($ arr)。'&lt; br&gt;&lt; br&gt;';
    // {“1”:“ dssdf“,”2“:”38904uj“}

    //跳过索引强制索引显示在JSON
    $ arr = array('0'=&gt;'dssdf','1'=&gt; '38904uj','3'=&gt;'321as5d4');
    echo json_encode($ arr)。'&lt; br&gt;&lt; br&gt;';
    // {“0”:“dssdf”,“1” :“38904uj”,“3”:“321as5d4”}

    // JSON_FORCE_OBJECT操作 tion force index
    $ arr = array('0'=&gt;'dssdf','1'=&gt;'38904uj');
    echo json_encode($ arr,JSON_FORCE_OBJECT)。'&lt; br&gt;&lt; br&gt; ';
    // {“0”:“dssdf”,“1”:“38904uj”}
    ?&gt;
    </ code> </ pre>
    </ div>

展开原文

原文

According to json.org:

JSON is built on two structures:

  • A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
  • An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.

I don't know if there are memory issues with this but consider the following code:

<?php
// No declared index causes no index in JSON
$arr = array('dssdf','38904uj');
echo json_encode($arr).'<br><br>';
// ["dssdf","38904uj"]

// start array at 0 removes the index from JSON
$arr = array('0'=>'dssdf','1'=>'38904uj');
echo json_encode($arr).'<br><br>';
// ["dssdf","38904uj"]

// start array at 1 forces the index to show in JSON
$arr = array('1'=>'dssdf','2'=>'38904uj');
echo json_encode($arr).'<br><br>';
// {"1":"dssdf","2":"38904uj"}

// skip an index forces the index to show in JSON
$arr = array('0'=>'dssdf','1'=>'38904uj','3'=>'321as5d4');
echo json_encode($arr).'<br><br>';
// {"0":"dssdf","1":"38904uj","3":"321as5d4"}

// JSON_FORCE_OBJECT option forces indexes
$arr = array('0'=>'dssdf','1'=>'38904uj');
echo json_encode($arr, JSON_FORCE_OBJECT).'<br><br>';
// {"0":"dssdf","1":"38904uj"}
?>

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问