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

Python/JSON加载的对象大小因文件大小而异,python,json,python-3.x,oop,memory,Python,Json,Python 3.x,Oop,Memory,最近,我在一个users.json文件中保存了数据,该文件需要花费大量时间才能加载到VsCode中,因为该文件太大,令我惊讶,因为它是一个29mb的文件,我想利用这个机会来处理pythons的内存使用情况,我将该文件全部加载到内存中,并按预期工作 虽然我有一个问题,但更多的我需要一个解释,原谅我,如果它的答案太明显 当我对加载的json对象进行自省时,我发现对象大小1.3mb远小于文件系统MacOS上的文件大小29.6mb,这怎么可能呢?大小上的差异太大了,不容忽视。更糟糕的是,我有一个较小的文

最近,我在一个users.json文件中保存了数据,该文件需要花费大量时间才能加载到VsCode中,因为该文件太大,令我惊讶,因为它是一个29mb的文件,我想利用这个机会来处理pythons的内存使用情况,我将该文件全部加载到内存中,并按预期工作

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

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

导入json 打开“users.json”作为内嵌: data=json.loadinfle printf'对象项计数:{lendata:,}项\n对象大小:{data.\uuuuSizeOf.\uuuuuu:,}字节 使用sys.getsizeofdata将返回类似的结果,可能会有一些gc开销

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

从pathlib导入路径 路径'users.json'.stat.st_size 请有人向我解释一下发生了什么,人们会认为大小应该相似,或者我错了。

不会在对象中重现:

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

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

为了得到更准确的结果,您可以

在加载前和加载后测量Python进程的内存使用情况,例如。 使用内存分析器,例如。 尽管如此,有些对象在内存中比磁盘上小;例如,一个大的数字,比如36不会递归到对象中:

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

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

为了得到更准确的结果,您可以

在加载前和加载后测量Python进程的内存使用情况,例如。 使用内存分析器,例如。
尽管如此,有些对象在内存中比磁盘上小;例如,一个大的数字,比如36谢谢,是有意义的,但是如果我加载一个json文件,它被加载到一个对象中,这个对象不引用任何对象,而是应该引用它。对象中的数据在对象中,因此引用的说法仍然让我感到困惑。虽然python官方说应该使用getsizeof递归地查找容器大小及其所有内容,但这应该比imo更直观。这确实是一种误导。@nosahama只有当您误解python的数据模型和内容时,这才是一种误导。在这里,您断言对象中的数据在对象中,并且此对象不引用任何对象,这完全是错误的,参见上面的链接-Python的对象存储在blackbox堆空间中,它们从不包含任何内容,它们总是只引用其他对象。这是Python,不是C语言-不同的语言,不同的数据模型。@AKX重复的dict键不存在-根据定义,dict键是唯一的-,如果您改变任何共享对象,共享重复的对象将导致意外行为。@brunodesthuilliers我的意思是解析[{foo:bar},{foo:qux}]将很可能创建两个包含内容foo的字符串对象。正如您所知,字符串是不可变的,因此更智能的JSON解码器可以共享字符串和整数。@AKX确实更清晰;--只需注意foo`是一个有效的Python标识符,因此它已经被CPython运行时占用了,小整数的定义也随着时间的推移而改变,但不知道当前的规范是什么。但是,只要我们是talink immutable对象,json解析器确实可以实现更积极的缓存,但由于json文档通常都很小,因此就我而言,一个29mb的json文档是疯狂的,我不确定这种开销在大多数情况下会带来多大的改进。谢谢,这是有意义的,但是如果我加载一个json文件,它被加载到一个对象中,这个对象不引用任何对象,而是应该引用它。对象中的数据在对象中,因此引用的说法仍然让我感到困惑。虽然python官方说应该使用getsizeof递归地查找容器大小及其所有内容,但这应该比imo更直观。这确实是一种误导。@nosahama只有当您误解python的数据模型和内容时,这才是一种误导。在这里,您可以断言对象中的数据在对象中,并且
对象不引用任何对象是完全错误的cf上面的链接-Python的对象存储在黑盒堆空间中,它们从不包含任何内容,它们总是只引用其他对象。这是Python,不是C语言-不同的语言,不同的数据模型。@AKX重复的dict键不存在-根据定义,dict键是唯一的-,如果您改变任何共享对象,共享重复的对象将导致意外行为。@brunodesthuilliers我的意思是解析[{foo:bar},{foo:qux}]将很可能创建两个包含内容foo的字符串对象。正如您所知,字符串是不可变的,因此更智能的JSON解码器可以共享字符串和整数。@AKX确实更清晰;--只需注意foo`是一个有效的Python标识符,因此它已经被CPython运行时占用了,小整数的定义也随着时间的推移而改变,但不知道当前的规范是什么。但只要我们是talink immutable对象,json解析器确实可以实现更具攻击性的缓存,但由于json文档通常都很小,就我而言,29mb的json文档是疯狂的,我不确定这种开销在大多数情况下会带来多大的改进。