【问题标题】:Decode big amount of "JSON-like" data in Python quickly在 Python 中快速解码大量“类 JSON”数据
【发布时间】:2017-12-15 20:58:07
【问题描述】:

假设有许多(大约 300,000 个)JSON 文件需要很长时间(大约 30 分钟)才能加载到 Python 对象列表中。分析显示,实际上花费大部分时间的不是文件访问,而是解码。有没有可以将这些文件转换成的格式,可以更快地加载到 python 对象列表中?

我的尝试:我将文件转换为 ProtoBuf(又名 Google 的 Protocol Buffers),但即使我得到的文件非常小(减少到原始大小的约 20%),加载它们的时间并没有显着改善(加载它们仍然超过 20 分钟)。

【问题讨论】:

  • 试试MessagePack (msgpack-python)。使用通用数据结构不会比这更快。当然,您始终可以定制您的格式以适合您的数据以挤出最后一盎司的性能,但那时我会首先重新考虑我的策略。

标签: python json performance decode file-format


【解决方案1】:

您可能正在寻找错误的转换方向,因为它可能不会像您希望的那样缩短加载时间。如果解码需要很多时间,那么其他格式也可能需要相当长的时间,假设 JSON 解码器写得不是很糟糕。我假设标准库函数有不错的实现,并且 JSON 在数据存储速度方面并不是一种糟糕的格式。

您可以尝试使用PyPy 运行您的程序,而不是我假设您正在使用的默认 CPython 实现。 PyPy 可以极大地减少执行时间。它有一个更快的 JSON 模块并使用 JIT,这可能会大大加快您的程序

如果您使用的是 Python 3,您也可以尝试使用ProcessPoolExecutor 同时运行文件加载和数据反序列化/解码。您将不得不试验并发程度,但一个好的起点是您的 CPU 内核数量,您可以将其减半或加倍。如果你的程序等待I/O很多,你应该运行更高的并发度,如果I/O的度数较小你可以尝试降低并发度。如果您编写每个执行程序,以便它们将数据加载到 Python 对象中并简单地返回它们,您应该能够显着减少加载时间。请注意,您必须使用进程驱动的方法,使用线程将不适用于GIL

您还可以使用faster JSON library,它可以在最佳情况下将您的执行时间加快两到三倍。在实际用例中,加速可能会更小。 请注意,这些可能不适用于 PyPy,因为它使用替代的 CFFI 实现,并且不适用于 CPython 程序,而且 PyPy 有一个很好的 JSON 模块。

【讨论】:

  • 使用ProcessPoolExecutor 的建议对我来说非常有价值! ProtoBuf + ProcessPoolExecutor 的执行时间现在只有约 5 分钟。至于其他建议(尤其是 PyPy),我将不得不在以后尝试它们。现在这已经足够好了。哦,谢谢你:)
【解决方案2】:

试试ujson,会快很多。

“解码需要大部分时间”可以看作是“构建 Python 对象需要所有时间”。你真的需要所有这些东西作为 RAM 中的 Python 对象吗?应该不少吧。

我会考虑使用适当的数据库,例如查询这种大小的数据。

如果您需要其他类型的批量处理,例如统计或矩阵处理,我会看看pandas

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-02
    • 1970-01-01
    • 2015-09-06
    • 1970-01-01
    相关资源
    最近更新 更多