在不杀死内存的情况下加载一个编码为Json的单个大型Python字典?

时间:2012-05-04 21:10:29

标签: python json

我已经看到了很多类似的问题,但没有真正匹配的问题。大多数其他问题似乎与速度有关。我正在经历的是一个单独的json字典,当我尝试使用以下任何内容加载它时,我的本地盒子上的1.1gig文件占用了我所有的16 GB内存:

f = open(some_file, "rb")
new_dictionary = json.load(f)

无论我使用什么json库(我尝试过ujson,json,yajl),无论我是否以字节流方式读取内容,都会发生这种情况。这对我来说完全没有意义。什么是疯狂的内存使用,我该如何解决它?

如果有帮助,字典只是一堆嵌套字典,所有字符都指向其他整数。示例如下:

{"0":{"3":82,"4":503,"15":456},"956":{"56":823,"678":50673,"35":1232}...}

UPDATE:当我使用simplejson运行它时,实际上只需要8次演出。不知道为什么那个人比其他人占用的少得多。

更新2:所以我做了一些调查。我用simplejson加载了我的字典,并尝试将所有键转换为int(根据Liori的建议,字符串可能会占用更多空间)。 8演出的空间保持不变。然后我尝试了Winston Ewert建议运行gc.collect()。空间仍然是8演出。最后,烦恼和好奇,我腌制我的新数据结构,退出Python,并重新加载。瞧,它仍然需要8演出。我想Python只是想要一个大的2d字典的空间。令人沮丧,当然,但至少现在我知道这不是JSON问题,只要我使用simplejson加载它。

4 个答案:

答案 0 :(得分:3)

您可以尝试使用流媒体API:

http://lloyd.github.com/yajl/

其中有几个python包装器。

https://github.com/rtyler/py-yajl/

https://github.com/pykler/yajl-py

答案 1 :(得分:2)

我的一些小实验表明,在解析了json对象之后调用gc.collect()会将内存使用量降低到最初构造对象时的位置。

以下是我在较小规模上使用内存的结果:

Build. No GC
762912
Build. GC
763000
Standard Json. Unicode Keys. No GC
885216
Standard Json. Unicode Keys. GC
744552
Standard Json. Int Keys. No GC
885216
Standard Json. Int Keys. GC
744724
Simple Json. Unicode Keys. No GC
894352
Simple Json. Unicode Keys. GC
745520
Simple Json. Int Keys. No GC
894352
Simple Json. Int Keys. GC
744884

基本上,运行gc.collect()似乎可以在JSON解析过程中清除某种类型的垃圾。

答案 2 :(得分:0)

我无法相信我要说这个,但json实际上是一种非常简单的格式,构建自己的解析器也不会太难。

那就是说,只有:

才有意义
  • 您最后不需要完整的字典(即,您可以在阅读时使用数据)
  • 你很清楚数据所处的结构类型(任意深度的字典会使这更加困难)

答案 3 :(得分:0)

Gabe在评论中确实发现了这一点,但由于已经过了几个月并且他没有将其作为答案发布,我认为我应该回答我自己的问题,所以后人看到有答案。< / p>

无论如何,答案是2d字典在Python中占用了那么多空间。这些词典中的每一个都有一些空间开头,因为它们有很多,它从1.1演出到8演出,除了尝试使用不同的数据结构或获得更多,你无能为力冲压。