【问题标题】:Fastest implementation of `ast.literal_eval``ast.literal_eval` 的最快实现
【发布时间】:2023-03-21 08:47:01
【问题描述】:

我有一些可以通过ast.literal_eval 解析的文本(strbytes;实际上是压缩在磁盘上的一个文件中)。

(它由一个dict列表组成,其中dict键是字符串,值是字符串,int或float。但也许这个问题对于任何可以通过ast.literal_eval解析的字符串都是通用的。)

它很大:~22MB 未压缩。

解析它的最快方法是什么?

我当然可以使用ast.literal_eval,但这似乎很慢。标准的eval 稍快一些(有趣的是,但可能与预期的一样,这取决于您对 Python 的了解程度;请参阅ast.literal_eval 的实现),但仍然很慢。

相比之下,当我将相同的数据序列化为 JSON,然后加载 JSON (json.loads) 时,这 方式 更快 (>10 倍)。所以这表明原则上应该可以同样快地解析它。

一些统计数据:

Gunzip + read time: 0.15111494064331055
Size: 22035943
compile: 3.1023156170000004
parse: 3.3381092380000004
eval: 3.0252232049999996
ast.literal_eval: 3.765798232
json.loads: 0.2657175249999994

可以找到此基准脚本以及生成此类虚拟文本文件的脚本:here

(也许答案是:“这需要更快的 C 实现;还没有人实现过”)


好的,在发布这个之后,我发现了一些相关的问题。我没有通过 Google 找到它们(也许我的搜索词“faster literal_eval”很糟糕)。

这部分回答了这个问题。

【问题讨论】:

  • 为什么不保存为 JSON?
  • 正如所写,这与 StackOverflow 无关。
  • @user2357112supportsMonica 我只是对这个问题感到好奇。当然我可以将它保存为 JSON,但我还是想知道。另外,我没想到会有这么大的差异。
  • 仅供参考,有更快的 Python 实现 JSON github.com/ultrajson/ultrajson
  • @Albert 很公平——有些人认为你的问题足够集中,我重新投票。对我来说,这是一个特殊性的问题——我并不是说你不能衡量任何东西,只是界限需要相当清楚。问题似乎仍然归结为,如果数据是有效的 JSON,那么最快的 JSON 解析器是什么,而不是在似乎不需要的 JSON 超集上运行的ast.literal_eval。如果你的数据是 JSON 的一个子集,比如说,只有整数值,也许你可以利用它。

标签: python


【解决方案1】:

因此,据我所知,目前不存在比ast.literal_eval 更快的实现(嗯,eval 本身要快一点,但不安全)。

所以我实现了自己的简单实现,它将文字 Python 代码转换为等效的二进制 Pickle 数据。 因此,对于某些字节 data,而不是 ast.literal_eval(data.decode("utf8")),您将使用 pickle.loads(py_to_pickle(data)),并获得 5.5 倍的加速。

回购是here。 这是一个在 C++ 中非常简单的实现,您可以轻松地直接将它与 ctypes 一起使用(repo 中有一个示例)。

新统计数据:

Gunzip + read time: 0.1663219928741455
Size: 22540270
py_to_pickle: 0.539439306
pickle.loads+py_to_pickle: 0.7234611099999999
compile: 3.3440755870000003
parse: 3.6302585899999995
eval: 3.306765757000001
ast.literal_eval: 4.056752016000003
json.loads: 0.3230752619999997
pickle.loads: 0.1351051709999993
marshal.loads: 0.10351717500000035

【讨论】:

    猜你喜欢
    • 2018-12-15
    • 1970-01-01
    • 2023-03-29
    • 2010-09-11
    • 1970-01-01
    • 1970-01-01
    • 2020-09-07
    • 1970-01-01
    相关资源
    最近更新 更多