“等效”从不匹配的正则表达式的时间完全不同?

2024-04-16

我最近为这个问题计时了一堆正则表达式“永远不会与任何内容匹配的正则表达式 https://stackoverflow.com/questions/1723182/a-regex-that-will-never-be-matched-by-anything" (我的回答在这里 https://stackoverflow.com/questions/1723182/a-regex-that-will-never-be-matched-by-anything/47115569#47115569,请参阅 参考资料 了解更多信息)。

然而,经过我的测试,我注意到正则表达式'a^' and 'x^'尽管它们应该是相同的,但检查所花费的时间却截然不同。 (我什至只是偶然切换了角色。)这些时间如下。

In [1]: import re

In [2]: with open('/tmp/longfile.txt') as f:
   ...:     longfile = f.read()
   ...:     

In [3]: len(re.findall('\n',longfile))
Out[3]: 275000

In [4]: len(longfile)
Out[4]: 24733175

...

In [45]: %timeit re.search('x^',longfile)
6.89 ms ± 31.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [46]: %timeit re.search('a^',longfile)
37.2 ms ± 739 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [47]: %timeit re.search(' ^',longfile)
49.8 ms ± 844 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

在线测试(仅前 50 行)显示了相同的行为(1441880 个步骤和约 710 毫秒 vs 仅 40858 个步骤和约 113 毫秒):https://regex101.com/r/AwaHmK/1 https://regex101.com/r/AwaHmK/1

Python 在这里做了什么使得'a^'花费的时间比'x^'?


只是为了看看里面有没有发生什么timeit或者 IPython,我自己编写了一个简单的计时函数,一切都检查完毕:

In [57]: import time

In [59]: import numpy as np

In [62]: def timing(regex,N=7,n=100):
    ...:     tN = []
    ...:     for i in range(N):
    ...:         t0 = time.time()
    ...:         for j in range(n):
    ...:             re.search(regex,longfile)
    ...:         t1 = time.time()
    ...:         tN.append((t1-t0)/n)
    ...:     return np.mean(tN)*1000, np.std(tN)*1000
    ...: 

In [63]: timing('a^')
Out[63]: (37.414282049451558, 0.33898056279589844)

In [64]: timing('x^')
Out[64]: (7.2061508042471756, 0.22062989840321218)

我还在 IPython 之外以标准方式复制了我的结果3.5.2壳。所以奇怪之处并不局限于 IPython 或timeit.


正如链接问题中提到的,这个正则表达式扫描整个文本.

这里看到的时间差异只是因为“a”在英文文本中是一个很常见的字母,而你使用了readable数据。因此,如果您研究正则表达式引擎如何工作,您就会明白:使用模式a^由于在第一个“a”上找到了暂时的匹配项,导致更多的延迟,然后又被拒绝。该引擎有两个“读取头”,它们都从左向右移动 - 一个在字符串中移动,另一个在正则表达式模式中移动。使用a^模式与您选择的人类可读数据相结合,正则表达式引擎必须做更多的工作。由于“x”在语料库中是一个不常见的字母,因此使用模式x^浪费更少的时间 - 可以立即拒绝文本中的更多位置。

  • 如果您以另一个常见字母(例如“e”)开始该模式,它也会同样慢(使用e^甚至会比a^,因为“e”在英语中出现的频率更高)。
  • 如果您对语料库使用随机 ascii 字节,而不是真实文本,则两者a^ and x^模式将执行类似的操作。

总之,这两个“等效”的永不匹配的正则表达式模式a^ and x^考虑到正则表达式引擎的内部工作和所选测试数据的更广泛背景,实际上并不那么等效。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

“等效”从不匹配的正则表达式的时间完全不同? 的相关文章

随机推荐

  • 如何获取 Oid 的名称(#Snmp)?

    好的 按照建议Lex Li https stackoverflow com users 11182 lex li我尝试使用其他库获取 Oid 名称 SnmpLib http sharpsnmplib codeplex com 这里是示例 p
  • 网络响应超时错误 (create-react-native-app) (expo)

    我正在尝试在 android 中的 expo 应用程序上运行 create react native app 首先 我通过编写命令创建了项目 创建反应本机应用程序测试 然后我执行了 npm 启动 然后从expo应用程序扫描二维码 但扫描二维
  • Spring Boot Mongodb 按 ID 搜索返回 null

    我用 mongodb 创建了一个 Spring Boot 项目 当我将数据插入集合时 它会被插入 但是当我尝试从中获取数据时findOne by id基于 id 的插入值总是返回 null 我在下面给出了我的模型类和插入方法 请告诉我出了什
  • 如何在 DLL 上使用 app.config 而不是 exe

    这是一个姐妹问题以及我的第一个问题允许使用 NET 2 0 构建的 C 应用程序在 NET 4 0 4 5 上运行 https stackoverflow com questions 13461185 allow c sharp appli
  • Selenium - 在检查 HTML 之前找不到可见元素?

    我目前正在使用 Selenium 进行网络爬虫应用程序 在几个成功的模块之后 以下情况让我陷入困境 我试图找到 菜单 类的一个元素 其文本 报告 位于名为的框架内 框架 应用 很简单 对吧 应该很简单 browser webdriver C
  • 扫描仪双值 - InputMismatchException

    我尝试以最简单的方式使用扫描仪 Code double gas efficiency distance cost Scanner scanner new Scanner System in System out print Enter th
  • MongoDB更新数组的多条记录[重复]

    这个问题在这里已经有答案了 我最近开始使用 MongoDB 并且有一个关于更新文档中的数组的问题 我得到这样的结构 id ObjectId post comments user test avatar static avatars asd
  • 实体框架级联删除问题-外键设置为空

    我有以下使用实体框架映射的模型 Mitglied gt Auftrag gt Teilprojekt 我已经用外键和 删除级联 设置了数据库中的所有内容 如果我对数据库执行一些测试 一切都会正常 当我使用实体框架添加尤其是删除对象时 问题就
  • 生成 PDF 格式的 Crystal 报告...如何在新选项卡或页面中打开?

    我编写了一段代码来生成 PDF 格式的 Crystal Reports 报告 但是它在用户进行搜索并单击按钮的同一页面中打开 有什么方法可以在新选项卡或页面中打开 PDF 我的代码是 private void OpenPDF ReportD
  • Word 2007 VBA - 使一些文本变为粗体和其他斜体

    我有以下代码 用于从 Excel 单元格中选择数据并替换 Word 文档中的特定文本 出于此问题的目的 Excel 单元格已替换为纯文本字符串 数据 转到 是恒定的 那么数据 aaa bbb 可以是任何内容 直到我们到达 of 它也是恒定的
  • Idris - 在 n 维向量上映射操作

    我在 Idris 中定义 n 维向量如下 import Data Vect NDVect Num t gt rank Nat gt shape Vect rank Nat gt t Type gt Type NDVect Z t t NDV
  • 如何在 Luigi 中启用动态需求?

    我在 Luigi 中构建了一个任务管道 由于该管道将在不同的上下文中使用 因此可能需要在管道的开头或结尾包含更多任务 甚至任务之间的依赖关系完全不同 就在那时我想 嘿 为什么要在我的配置文件中声明任务之间的依赖关系 所以我在 config
  • 抽象类、接口和自动装配

    我有以下主要课程 public class Startup implements UncaughtExceptionHandler Autowired private MessageListener messageListener priv
  • 如何清空字符数组?

    有一个像 char Members 255 这样的字符数组 如何在不使用循环的情况下完全清空它 char members 255 我所说的 空 是指如果它存储了一些值 那么它就不应该 例如 如果我执行 strcat 那么旧值不应保留 mem
  • 手动合并拉取请求

    所以我在github上有以下情况 我从创建了一个新分支mainbranch并命名为userstory1 我在分支中推送了我的更改userstory1并向我的同事提出了拉取请求 他发现文件夹结构不正确 因此将我的代码文件夹重命名为mainbr
  • 如何在 XLOPER 和 VARIANT 之间编组? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在开发一个 Excel 插件 XLL 它与 COM 对象进行通信 所以 我必须在 XLOPER 和
  • Blazor按钮,使用父组件@onclick

    是否可以使用父组件方法 onclick 或者我需要从子组件中调用它 假设我想调用父方法 Foo Parent page Custom component button
  • 收到错误消息 - 创建签名 apk 时“条目名称 'res/layout/test_toolbar.xml' 发生冲突”

    我已经更新了我的 android studio3 5 x to 3 6今天 在为构建变体生成签名 apk 时出现错误 显示以下消息 Entry name res layout test toolbar xml 相撞 我在整个项目中根本没有任
  • 如何从 Github 和 Bitbucket 上的 git 删除提交

    我不小心从 Django 项目中的 idea 目录中推送了文件 这些文件位于 gitignore 文件中 我正在尝试从我的 bitbucket 存储库中完全删除提交 因为我正在与该项目一起工作的其他人 并且他无法在不影响他自己的 idea
  • “等效”从不匹配的正则表达式的时间完全不同?

    我最近为这个问题计时了一堆正则表达式 永远不会与任何内容匹配的正则表达式 https stackoverflow com questions 1723182 a regex that will never be matched by any