【问题标题】:Python: why regular expression is slower than replace() method?Python:为什么正则表达式比 replace() 方法慢?
【发布时间】:2012-06-30 19:00:14
【问题描述】:

我有接下来的 2 块代码:

def replace_re(text):
    start = time.time()
    new_text = re.compile(r'(\n|\s{4})').sub('', text)
    finish = time.time()
    return finish - start

def replace_builtin(text):
    start = time.time()
    new_text = text.replace('\n', '').replace('    ', '')
    finish = time.time()
    return finish - start

我用文本参数调用这两个函数(一个网页的源代码约为 500kb)。 我以为replace_re() 会快得多,但结果是下一个:

  1. replace_builtin() ~ 0.008 秒
  2. replace_re() ~ 0.035 秒(几乎 4.5 倍慢!!!)

这是为什么呢?

【问题讨论】:

  • 为什么正则表达式不会更慢?正则表达式引擎比遍历字符串和检查匹配要昂贵得多。
  • +1 用于分析,以及显示您的代码和结果。这是一个合理的问题,即使许多回答都将其视为常识。

标签: python regex


【解决方案1】:

因为正则表达式比固定字符串替换复杂更多

【讨论】:

  • 这可能是真的,但您没有为该声明提供任何支持信息。这并不是很有用,也没有以有意义的方式回答 OP 的问题。
  • 我认为这没有帮助,@VitaliPonomar 为什么这是一个不错的答案?仅仅因为这几乎是常识?
  • @zinking 我的意思是有趣的答案。如您所见,我接受了另一个最有帮助的答案...
【解决方案2】:

因为re 必须生成 FSM。然后用它来处理字符串。而替换可以使用更接近 lib/OS 级别的底层字符串处理函数。

【讨论】:

    【解决方案3】:

    考虑每个空格字符在源字符串中发生的情况——正则表达式引擎必须探索接下来的三个字符以查看它们是否也是空格。因此,每个空格本质上都涉及查看下一个字符。大多数 RE 引擎写得并不那么……直截了当地说……但它本质上意味着引擎必须返回到启动状态,并有可能丢弃它在之前正在构建的匹配状态中建立的数据。

    但是,在字符串中搜索固定模式(四个空格)实际上可以在sub-linear time 中完成。我不知道 Python replace() 是否以这种方式实现,但希望他们已经很好地使用了他们可以使用的工具。

    【讨论】:

    • +1 用于链接到 Boyer-Moore ......不过,不像你需要代表。 :)
    【解决方案4】:

    经验法则

    固定字符串匹配应该总是比正则表达式匹配更快。您可以在 Google 上搜索各种基准,或者按照自己的方式执行并执行自己的基准,但通常您可以假设这将是正确的,除非(可能)在一些不寻常的边缘情况下。

    为什么正则表达式比较慢

    为什么这是真的与固定字符串匹配没有回溯、编译步骤、范围、字符类或许多其他减慢常规的特性有关表达引擎。当然有优化正则表达式匹配的方法,但我认为在常见情况下它不太可能击败对字符串的索引。

    使用源代码

    如果您想要更好的解释,您可以随时查看相关模块的源代码,了解它们是如何工作的。这肯定会为您提供有关任何特定实现为何如此执行的更多信息。

    【讨论】:

      猜你喜欢
      • 2018-05-08
      • 1970-01-01
      • 2012-12-21
      • 2015-09-18
      • 2019-03-12
      • 2012-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多