Python/JSON加载的对象大小因文件大小而异



最近,我在一个users.json文件中有数据,由于该文件太大,需要花费大量时间才能加载到VsCode中(因为它是29mb文件,所以我很惊讶(,我想利用这个机会来利用蟒蛇的内存使用情况,我将文件全部加载到内存中,并按预期工作。

虽然我有一个问题,但我更需要解释,如果答案太明显,请原谅我;

当我对加载的json对象进行内省时,我发现对象大小(1.3mb(远小于我的文件系统(MacOS(上的文件大小(29.6mb(,这怎么可能呢?尺寸上的差异太大了,不容忽视。更糟糕的是,我有一个较小的文件,该文件返回了类似大小的结果(在磁盘上/已加载,~358kb(,哈哈。

import json
with open('users.json') as infile:
data = json.load(infile)
print(f'Object Item Count: {len(data):,} items nObject Size: {data.__sizeof__():,} bytes)

使用sys.getsizeof(data)会返回类似的东西,可能会有一些gc开销。

这将返回磁盘上文件的准确大小(29586765字节,29mb(

from pathlib import Path
Path('users.json').stat().st_size

请有人向我解释一下发生了什么,有人会认为应该在大小上相似,或者我错了。

sys.getsizeof()不会递归到对象中:

只考虑直接归因于对象的内存消耗,而不考虑它所指对象的内存损耗。

从JSON文件加载的所有字符串、数字等都是前面提到的"引用的对象"。

为了获得更准确的结果,您可以使用

  • 测量Python进程加载前后的内存使用情况(例如。https://stackoverflow.com/a/21632554/51685)
  • 使用内存探查器(例如,建议使用哪种Python内存探查器?(

也就是说,有些对象在内存中会比在磁盘上更小;例如,一个大的数字,比如说36 << 921在磁盘上是279字节,而sys.getsizeof()在内存中把它固定在148字节。类似地,一个足够智能的JSON解码器(

,afaik,内置的json,而不是,默认的JSON解码器实际上是,请参阅https://github.com/python/cpython/commit/7d6e076f6d8dd48cfd748b02dad17dbeb0b346a3)可以共享用于重复dict键的对象。

最新更新