Python json.load是否效率低下?

Python json.load是否效率低下?,python,json,Python,Json,我正在查看json模块的源代码,试图回答另一个问题,这时我发现了一些奇怪的东西。除去docstring和一大堆关键字参数,json.load的源代码如下: def load(fp): return loads(fp.read()) 这一点也不像我预料的那样。如果json.load不能避免一次读取整个文件的开销,那么它比json.load(f.read())节省几个字符的源代码的唯一优势是什么?它为什么会存在?为什么它得到的是短名称,而不是loads得到的是loads名称和loadf这样

我正在查看
json
模块的源代码,试图回答另一个问题,这时我发现了一些奇怪的东西。除去docstring和一大堆关键字参数,
json.load
的源代码如下:

def load(fp):
    return loads(fp.read())

这一点也不像我预料的那样。如果
json.load
不能避免一次读取整个文件的开销,那么它比
json.load(f.read())
节省几个字符的源代码的唯一优势是什么?它为什么会存在?为什么它得到的是短名称,而不是
loads
得到的是
loads
名称和
loadf
这样的名称?我能想到原因(例如复制
pickle
接口),但有人能提供权威的答案而不是猜测吗?

尽管期待
json是很自然的事。load()
做得更好,正如评论中提到的,但它不能保证做到这一点。这纯粹是推测,但如果我是Python维护人员,我会设计简单且维护开销最小的模块

Python标准库
json
模块在速度和内存使用方面都不是最优的。对于不同的最佳点,有许多替代JSON读取实现,其中一些具有Python绑定,例如:


替代JSON实现源于以高效方式处理流和/或大量数据的必要性。

可以肯定地说,从文件读取JSON虽然很重要,但不是JSON序列化的主要用例。因此,从文件实现高效的JSON加载并不是那么有趣,除非是在特殊情况下(有更有效的方法将大型数据结构序列化到磁盘)

然而,概括这个概念可能会引入一些有用的方面(例如,来自网络流的JSON反序列化,或者来自管道的渐进式JSON反序列化)

然后我们要寻找的是一个流式解析器(例如,像用于XML的SAX)。是一个常见的语法分析器,并且有很多方法可供使用


也可以看到这个问题的最上面的答案:

我认为你的
pickle
想法不仅仅是猜测。
json
模块文档中说,“
json
公开了标准库
marshal
pickle
模块用户熟悉的API”,这强烈表明这是有意的。当然可能还有另一个原因。你为什么认为它效率低下?最终必须读取整个文本,因此执行单个
读取
可以最大限度地减少I/O时间。此外,如果文件的文本不能保留在RAM中,那么几乎可以肯定结果不会保留在RAM中。拥有所有可用的文本可以避免在解析过程中处理问题,这可能会显著加快解析速度。如果你想发送千兆字节的数据,你无论如何都不应该使用
json
,所以我看不出这个选择有什么错。@Bakuriu然而,如果字符串占用了约50%的内存,而解析的对象占用了约75%的内存,那么
load
(如上实现)将失败。另一方面,逐块解析文件也可以。所以它在内存方面效率很低。虽然有点抽象。谁在和这么大的JSON一起工作?@怪怪的,这是我的观点。如果字符串占用了约50%的内存,则不应使用
json
,而应使用更高效的编码。事实上,你不应该试图解码占用那么多RAM的对象,因为一个~75%RAM大小的对象无论如何都会让计算机交换很多东西。@Bakuriu:我知道这一点。但是,它没有回答为什么存在
json.load
或者是否“应该”使用它的问题。我提出了一系列的理由来解释为什么
load
可以这样实现,但是它们都是推测性的,没有一个能回答我是否应该和如何强烈地喜欢它而不是
load(f.read())
“从文件中实现一个高效的JSON加载并没有那么有趣”——不过,如果
read()的话,这会很有趣
从二进制模式文件返回一个类似字节序列的对象,它只是文件(部分)只读内存映射的写时拷贝包装器:-),这确实很有趣,尽管我怀疑它在字符串编码上会失败。数据blob是base64,常规字符串是UTF-8,两者都不是很有用。