【问题标题】:Python 2.6 JSON decoding performancePython 2.6 JSON 解码性能
【发布时间】:2010-10-16 21:45:23
【问题描述】:

我正在使用 Python 2.6 中的 json 模块来加载和解码 JSON 文件。但是,我目前的表现比预期的要慢。我正在使用一个大小为 6MB 的测试用例,json.loads() 需要 20 秒。

我认为json 模块有一些本机代码来加速解码?

如何检查是否正在使用?

作为比较,我下载并安装了python-cjson 模块,而cjson.decode() 对相同的测试用例需要1 秒。

我宁愿使用 Python 2.6 提供的 JSON 模块,这样我的代码的用户就不需要安装额外的模块。

(我在 Mac OS X 上进行开发,但在 Windows XP 上得到了类似的结果。)

【问题讨论】:

  • 这在 Python 2.7 中得到了解决,根据下面Tomas、Ivo、TONy.W 的比较数字。标记了这个 python-2.6
  • (根据 TONy.W 的数字,剩下的唯一问题是 stdlib json encode 在 2.7 中仍然慢 2 倍)

标签: python json python-2.6


【解决方案1】:

新的Yajl - Yet Another JSON Library 非常快。

yajl        serialize: 0.180  deserialize: 0.182  total: 0.362
simplejson  serialize: 0.840  deserialize: 0.490  total: 1.331
stdlib json serialize: 2.812  deserialize: 8.725  total: 11.537

你可以compare the libraries yourself

更新:UltraJSON 更快。

【讨论】:

  • 感谢 ujson 链接;)它在我的 gevent/redis 搜索服务上给了我额外的 400 请求/秒。
  • 我自己尝试了测试并获得了非常有竞争力的结果。根本没有获得 20 倍的加速。使用比较脚本(来自提供的链接)和大型 JSON (20MB) - 性能仍然非常可比。
【解决方案2】:

可能因平台而异,但内置 json 模块基于simplejson,不包括 C 加速。无论如何,我发现 simplejson 和 python-cjson 一样快,所以我更喜欢它,因为它显然具有与内置相同的接口。

try:
    import simplejson as json
except ImportError:
    import json

在我看来,这是一段时间以来最好的习惯用法,在向前兼容的同时提供可用的性能。

【讨论】:

  • fwiw, 11nov 2009 pypi.python.org/packages/source/s/simplejson/… on mac 10.4.11 ppc, gcc 4.2.1 => simplejson/_speedups.c:2256: error: redefinition of 'PyTypeObject PyEncoderType' 警告: C 扩展可能未编译,未启用加速。
  • 如果py-yajilultrajson 更快,那么使用simplejson 除了看起来与json 相同并且是纯Python 之外还有什么好处?
  • @Shurane 既不支持 py-yajl 也不支持 ultrajson 支持 json 所做的所有参数。 simplejsonjson 快(由于 C 加速)和直接替换。
  • 不再。许多新的 json 模块更快。
  • 最近有调查过吗?我在 3.6 中进行 json 解码的业余时间给了我,json 比 simplejson 或 ujson 更快(使用小文件)(无论如何,这似乎不再维护了)。
【解决方案3】:

我正在解析同一个文件 10 倍。文件大小为 1,856,944 字节。

Python 2.6:

yajl        serialize: 0.294  deserialize: 0.334  total: 0.627
cjson       serialize: 0.494  deserialize: 0.276  total: 0.769
simplejson  serialize: 0.554  deserialize: 0.268  total: 0.823
stdlib json serialize: 3.917  deserialize: 17.508 total: 21.425

Python 2.7:

yajl        serialize: 0.289  deserialize: 0.312  total: 0.601
cjson       serialize: 0.232  deserialize: 0.254  total: 0.486
simplejson  serialize: 0.288  deserialize: 0.253  total: 0.540
stdlib json serialize: 0.273  deserialize: 0.256  total: 0.528

不确定为什么数字与您的结果不成比例。我猜,更新的库?

【讨论】:

  • 我还注意到 python 2.6 和 2.7 之间 stdlib(即内置)json 的显着性能差异。这就是为什么 python 2.7 比 2.6 更受欢迎的另一个原因。
  • 原因很简单:在 Python 2.7 中添加了 json 的 C 加速。来自发行说明:“更新的模块:json 模块已升级到 simplejson 包的 2.0.9 版,其中包括一个 C 扩展,使编码和解码更快。” docs.python.org/dev/whatsnew/2.7.html
  • +1 非常有价值的数字 Tomas。所以 2.7 解决了所有问题。
【解决方案4】:

看看 UltraJSON https://github.com/esnme/ultrajson

这是我的测试(代码来自:https://gist.github.com/lightcatcher/1136415

平台:OS X 10.8.3 MBP 2.2 GHz Intel Core i7

JSON:

simplejson==3.1.0

python-cjson==1.0.5

jsonlib==1.6.1

ujson==1.30

yajl==0.3.5

JSON Benchmark
2.7.2 (default, Oct 11 2012, 20:14:37)
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)]
-----------------------------
ENCODING
simplejson: 0.293394s
cjson: 0.461517s
ujson: 0.222278s
jsonlib: 0.428641s
json: 0.759091s
yajl: 0.388836s

DECODING
simplejson: 0.556367s
cjson: 0.42649s
ujson: 0.212396s
jsonlib: 0.265861s
json: 0.365553s
yajl: 0.361718s

【讨论】:

  • 截至 2014 年 8 月,这些结果在最新的库版本上大多是准确的。我们针对我们的一些随机数据进行了测试,ujson 略微(大约 5-10%)超过了 cjson,大约是 x2 simplejson 和 3x json。 cjson 在特定数据集上的性能也很不稳定,所以我们坚持使用 ujson。
【解决方案5】:

对于那些使用 requests 包解析请求输出的人,例如:

res = requests.request(...)

text = json.loads(res.text)

对于较大的响应内容,这可能会非常慢,比如我的 2017 MacBook 上 6 MB 的响应时间约为 45 秒。它不是由缓慢的 json 解析器引起的,而是由 res.text 调用的缓慢字符集确定引起的。

您可以通过在调用 res.text 之前设置字符集并使用cchardet 包(另请参阅here)来解决此问题:

if res.encoding is None:
    res.encoding = cchardet.detect(res.content)['encoding']

这使得响应文本 json 解析几乎是即时的!

【讨论】:

    【解决方案6】:

    查看我在 Windows 上安装的 Python 2.6.1,json 包加载了内置在运行时中的 _json 模块。 C 模块的json speedups 源是here

    >>> import _json
    >>> _json
    <module '_json' (built-in)>
    >>> print _json.__doc__
    json speedups
    >>> dir(_json)
    ['__doc__', '__name__', '__package__', 'encode_basestring_ascii', 'scanstring']
    >>> 
    

    【讨论】:

    • 我还假设带有 _json 的 json 会很快。基准证明我错了。
    • json在底层已经使用了_json C 模块。直接访问它几乎没有用处。
    【解决方案7】:

    尽管_json 可用,但我注意到 CPython 2.6.6 上的 json 解码非常慢。我没有与其他实现进行比较,但在性能关键循环中我已经切换到字符串操作。

    【讨论】:

      猜你喜欢
      • 2012-09-06
      • 1970-01-01
      • 2011-06-11
      • 2012-10-08
      • 2011-07-21
      • 2016-11-09
      • 1970-01-01
      • 2010-12-16
      • 1970-01-01
      相关资源
      最近更新 更多