解码大量的;类似JSON的;Python中的数据快速更新

解码大量的;类似JSON的;Python中的数据快速更新,python,json,performance,decode,file-format,Python,Json,Performance,Decode,File Format,假设有许多(大约300000)JSON文件需要花费很多时间(大约30分钟)才能加载到Python对象列表中。分析显示,事实上不是文件访问,而是解码,这占用了大部分时间。是否有一种格式可以将这些文件转换为,可以更快地加载到python对象列表中 我的尝试:我将文件转换为ProtoBuf(也称谷歌的ProtocolBuffers),但即使我得到了非常小的文件(减少到原始大小的约20%),加载它们的时间也没有显著提高(加载它们的时间仍然超过20分钟).您可能在转换时看到了错误的方向,因为它可能不会像您

假设有许多(大约300000)JSON文件需要花费很多时间(大约30分钟)才能加载到Python对象列表中。分析显示,事实上不是文件访问,而是解码,这占用了大部分时间。是否有一种格式可以将这些文件转换为,可以更快地加载到python对象列表中


我的尝试:我将文件转换为ProtoBuf(也称谷歌的ProtocolBuffers),但即使我得到了非常小的文件(减少到原始大小的约20%),加载它们的时间也没有显著提高(加载它们的时间仍然超过20分钟).

您可能在转换时看到了错误的方向,因为它可能不会像您希望的那样缩短加载时间。如果解码需要花费大量时间,那么其他格式也可能需要相当长的时间,假设JSON解码器编写得不是很糟糕。我假设标准库函数有不错的实现,JSON对于数据存储速度来说不是一种糟糕的格式

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

如果您使用的是Python3,那么还可以尝试使用同时运行文件加载和数据反序列化/解码。您必须测试并发度,但一个好的起点是CPU内核的数量,可以减半或翻倍。如果您的程序等待I/O时间过长,则应运行更高的并发度,如果I/O度较小,则可以尝试降低并发度。如果您编写每个执行器,以便它们将数据加载到Python对象中并简单地返回它们,那么您应该能够显著缩短加载时间。请注意,您必须使用流程驱动的方法,使用线程将无法使用


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

您可能在转换中看到了错误的方向,因为它可能不会像您希望的那样缩短加载时间。如果解码需要花费大量时间,那么其他格式也可能需要相当长的时间,假设JSON解码器编写得不是很糟糕。我假设标准库函数有不错的实现,JSON对于数据存储速度来说不是一种糟糕的格式

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

如果您使用的是Python3,那么还可以尝试使用同时运行文件加载和数据反序列化/解码。您必须测试并发度,但一个好的起点是CPU内核的数量,可以减半或翻倍。如果您的程序等待I/O时间过长,则应运行更高的并发度,如果I/O度较小,则可以尝试降低并发度。如果您编写每个执行器,以便它们将数据加载到Python对象中并简单地返回它们,那么您应该能够显著缩短加载时间。请注意,您必须使用流程驱动的方法,使用线程将无法使用

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

试试看,它的速度要快得多

“解码占用大部分时间”可以被视为“构建Python对象占用所有时间”。您真的需要所有这些东西作为RAM中的Python对象吗?一定很多

我会考虑使用适当的数据库来查询这样大小的数据。

如果您需要其他类型的大规模处理,例如统计数据或矩阵处理,我会看一下
pandas

试试,它会快一点

“解码占用大部分时间”可以被视为“构建Python对象占用所有时间”。您真的需要所有这些东西作为RAM中的Python对象吗?一定很多

我会考虑使用适当的数据库来查询这样大小的数据。


如果您需要其他类型的大规模处理,例如统计或矩阵处理,我会查看
pandas

Try()。使用通用数据结构,您不会比这更快。当然,您可以根据数据定制格式,以压缩最后一盎司的性能,但在这一点上,我会首先重新考虑我的策略。使用通用数据结构,您不会比这更快。当然,您可以随时定制您的格式,以适合您的数据,以挤出最后一盎司的性能,但在这一点上,我首先会重新考虑我的策略。使用
ProcessPoolExecutor
的建议已被证明对我非常有价值!ProtoBuf+
ProcessPoolExecutor
的执行时间现在只有~5分钟。至于其他建议(尤其是PyPy),我将在以后的日子里尝试。现在这已经足够好了。哦,谢谢:)建议使用