<p>所有这些库和实现都执行某种模式匹配,以查找要检查的文件部分。然后必须对所选元素执行操作,通常是将内容升级到Python数据结构中</p>
<p>默认情况下,一旦发生初始模式匹配,ijson就会将子文档复制到Python dict/list中。这要付出代价。如果您想用Python操作文档的一部分(而不是提取标量/字符串),仍然需要转换。如果使用C实现进行解析,则必须将C变量转换为Python变量</p>
<p>在处理必须大量加载的深层数据结构时,您可能会发现用C解析文件的好处与转换为Python的成本相比相形见绌,因此纯Python实现绕过了一些转换成本</p>
<p>jsonslicer(对我来说)对于简单的提取任务来说速度非常快,但随着提取复杂性的增加,它也会遇到类似的限制。我有一个970MB的未压缩JSON文件,其中包含一个文档列表。在我的例子中,从第三级属性中选择一个简单的字符串如下所示:</p>
<pre><code>with gzip.open('big_docs.json.gz') as file:
for thing in JsonSlicer(file, (None, 'key')):
# print(thing)
if thing == 'special_value':
pass
with gzip.open('big_docs.json.gz') as file:
for thing in ijson.items(file, 'item'):
if thing['key'] == 'special_value':
pass
</code></pre>
<ul>
<li>ijson(使用默认的C绑定)-363s</li>
<li>ijson(纯Python)-686s</li>
<li>jsonslicer-15s</li>
</ul>
<p>在这种不公平的比较中,jsonslicer能够以几乎零的成本避免将字符串以外的任何东西转换为Python,因此结果非常快。我天真的ijson用法必须做更多的工作</p>
<p>在本例中,如果我在不改变交互的情况下深入挖掘两层,我会得到:</p>
<ul>
<li>ijson-350s</li>
<li>ijson(纯python)-667s</li>
<li>jsonslicer-16s</li>
</ul>
<p>jsonslicer的速度稍慢,需要检查的内容更多,而ijson也会这样做,但通过对较小的文档节进行建模来获得时间。更复杂的用途会改变平衡。证明从C到Python的转换是你看不见的代码变慢的原因是困难的,但这可能是有帮助的</p>