grep -f 的性能问题

2024-02-09

我正在使用 grep 在单个文件中搜索多个正则表达式。 特别是,我正在考虑100 MB 文件,带英文字幕 https://drive.google.com/open?id=0B3oOQ14-tellNzhlU0tKT2xFSW8并运行存储在文件中的以下正则表达式模式.txt:

Cas.*eharden
acr.*otic
syn.*thesizing
sub.*abbot
iss.*acharite
bot.*onne
dis.*similatory
ove.*rmantel
isa.*tin
ado.*nijah
sol.*ution
zei.*st
fam.*ousness
inq.*uisitress
aor.*tography
via.*duct
ama.*sa
der.*ive
pie.*tas
kit.*chenette

在这样做时,我观察到 grep 所需的时间并不随着正则表达式的数量线性增长。的确,它似乎呈指数级增长.

实验

System:英特尔(R) 酷睿(TM) i5-5200U CPU @ 2.20GHz; 4 核; 8GB 内存

案例 1:20 个正则表达式

Command grep -c -f patterns.txt subtitles.txt统计 2214 次出现并采取
2,19s 用户 0,00s 系统 99% cpu 总计 2,192。

案例 2:30 个正则表达式

如果我添加以下表达式模式.txt

ort.*hros
ove.*ridentify
mis.*tiest
pay.*ne
int.*erchasing
jej.*uneness
sta.*lactiform
und.*ertrain
cob.*bles
Sub.*category

Command grep -c -f patterns.txt subtitles.txt统计了 2894 次出现,总共需要 71,35 秒用户 0,06 秒系统 99% cpu 1:11,42。

案例 3:35 个正则表达式

添加另外五个表达式:

dis.*embosom
imp.*ortunateness
ema.*thion
rho.*mb
haz.*elwood

Command grep -c -f patterns.txt subtitles.txt计数 2904 次出现,需要 211,18 秒用户 0,22 秒系统 99% cpu 3:31,58 总计

为什么 grep -f 表现出这样的行为?它在内部做什么?

我一直在使用的整套正则表达式都可以找到here https://drive.google.com/open?id=0B3oOQ14-tellOG5WcXBlRmFWY00


从阅读grep源代码中,您文件中的正则表达式似乎没有一次执行一个。相反,它们会被一次性读入一个大的正则表达式中:

case 'f':
  fp = STREQ (optarg, "-") ? stdin : fopen (optarg, O_TEXT ? "rt" : "r");
  if (!fp)
    error (EXIT_TROUBLE, errno, "%s", optarg);
  for (keyalloc = 1; keyalloc <= keycc + 1; keyalloc *= 2)
    ;
  keys = xrealloc (keys, keyalloc);
  oldcc = keycc;
  while ((cc = fread (keys + keycc, 1, keyalloc - 1 - keycc, fp)) != 0)
    {
      keycc += cc;
      if (keycc == keyalloc - 1)
        keys = x2nrealloc (keys, &keyalloc, sizeof *keys);
    }

这是通过观看证实的stracegrep 在您的命令上运行:

open("testreg", O_RDONLY)               = 3
fstat(3, {st_mode=S_IFREG|0664, st_size=124, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd8912fe000
read(3, "ort.*hros\nove.*ridentify\nmis.*ti"..., 4096) = 124

回溯正则表达式实现(允许反向引用)不会在 O(n) 时间内运行,而是在 O(2^m) 时间内运行,这可能会导致灾难性的 https://stackoverflow.com/questions/5892115/whats-the-time-complexity-of-average-regex-algorithms运行时。

你的假设grep只是依次循环每个正则表达式,将每个正则表达式编译成 DFA,然后执行它,这是完全合理的。然而,似乎grep作者假设,通过同时运行所有正则表达式,在某些情况下他们可能可以更有效地执行此操作。结果是,通过将正则表达式添加到文件中,您将陷入 O(2^m) 运行时间,从而导致运行时间呈指数增长。

事实证明,简单地循环每个正则表达式一次执行一个,强制 grep 线性运行可能会更有效。在我的笔记本电脑上,运行 grep 版本 2.20,我仅使用您提供的文件中的最后 29 个正则表达式得到以下结果:

[Downloads]$ wc -l patterns.txt 
29 patterns.txt

[Downloads]$ time grep -c -f ~/Downloads/patterns.txt /usr/share/dict/linux.words 
117

real    0m3.092s
user    0m3.027s
sys     0m0.047s

[csd@alcazar Downloads]$ time for regex in `cat ~/Downloads/patterns.txt`; do grep -c $regex /usr/share/dict/linux.words > /dev/null; done
real    0m0.474s
user    0m0.312s
sys     0m0.158s
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

grep -f 的性能问题 的相关文章

  • Draggable JS Bootstrap 模式 - 性能问题

    对于工作中的项目 我们在 JavaScript 中使用 Bootstrap Modal 窗口 我们想让一些窗口可移动 但我们遇到了 JQuery 的性能问题 myModal draggable handle modal header Exa
  • 在 SQLite 中搜索时排除 HTML 标签和一些 UNICODE 字符

    更新 4 我已经成功运行了firstchar例如 但现在的问题是使用regex 即使包含头文件 它也无法识别regex操作员 有什么线索可以解决这个问题吗 更新 2 我已经编译了sqlite3我的项目中的库 我现在正在寻找任何人帮助我为我的
  • 将字符串限制为逗号后 2 个数字且仅限 1 个逗号

    我有下面的脚本 只允许输入文本上的数字和逗号 function validate evt var theEvent evt window event var key theEvent keyCode theEvent which key S
  • 如何使用正则表达式将多个
    标签替换为一个
    标签?

    I want br br 变成 br 正则表达式的模式是什么 注 br 标签可以连续出现两次以上 html preg replace br gt s i br html 这将捕获任何组合 br br or br 它们之间有任意数量或类型的空
  • 用于多行字符串的 ECMAScript 正则表达式

    我正在为我的应用程序编写加载过程 它涉及从文件中读取数据并创建具有适当属性的适当对象 该文件由以下格式的连续条目 以换行符分隔 组成 OBJECT TYPE
  • hive regexp_extract 怪异

    我在 regexp extract 方面遇到一些问题 我正在查询制表符分隔的文件 我正在检查的列具有如下所示的字符串 abc def ghi 现在 如果我这样做 select distinct regexp extract name 0 f
  • 删除emacs中多余的空行

    M x flush lines 删除缓冲区中的所有空白行 但是我只想删除多余的空白行 也就是说 如果有n个连续的空白行我想删除n 1并保留一个 我知道删除空白行可以完成该点下的空白行的工作 但是我想要一个适用于整个缓冲区的简单解决方案 有什
  • Mxnet - 缓慢的数组复制到 GPU

    我的问题 我应该如何在 mxnet 中执行快速矩阵乘法 我的具体问题 数组复制到 GPU 的速度很慢 对此我们能做些什么呢 我创建随机数组 将它们复制到上下文中 然后相乘 import mxnet as mx import mxnet nd
  • 正则表达式(第一个字符匹配 a-z)

    我有这个正则表达式 a zA Z0 9 上面我想补充的是 第一个字符只能是a zA Z 我怎样才能制作这个正则表达式 尝试这样的事情 a zA Z a zA Z0 9 解释 Start of line string a zA Z Chara
  • 请解释*贪婪量词的工作原理

    Pattern ptn Pattern compile a Matcher mtch ptn matcher bbaac if mtch find System out println mtch group 输出 不打印任何内容 Patte
  • 数组与列表的性能

    假设您需要一个需要频繁迭代的整数列表 数组 我的意思是非常频繁 原因可能有所不同 但可以说它位于大容量处理的最内层循环的核心 一般来说 人们会选择使用列表 List 因为它们的大小具有灵活性 最重要的是 msdn 文档声称列表在内部使用数组
  • 正则表达式:匹配未包含在 [] 中的空格

    例如 对于这个字符串 div img wrapper img title Hello world 我想匹配第一个空格 但不匹配第二个空格 包含在 中 正则表达式是什么 以下表达式将通过使用前瞻断言来完成这项工作 gt 下划线代表空格 该表达
  • javascript 和 PHP 中的正则表达式有什么区别吗?

    这是在 javascript 中验证电子邮件地址的正则表达式 我不确定是否可以直接在 PHP 中使用它 a z d u00A0 uD7FF uF900 uFDCF uFDF0 uFFEF a z d u00A0 uD7FF uF900 uF
  • 使用正则表达式、kibana 搜索数组中的元素

    我正在搜索包含数组字段的记录payload params 我想显示包含该字符串的所有字段aabb 例子 payload params 3raabb 44aabb66 grgeg 展示 3raabb 44aabb66 如何在数组上使用正则表达
  • 提高第一个查询的性能

    如果执行以下数据库 postgres 查询 则第二次调用要快得多 我猜第一个查询很慢 因为操作系统 linux 需要从磁盘获取数据 第二个查询受益于文件系统级别和 postgres 中的缓存 有没有一种方法可以优化数据库以快速获得结果fir
  • 使用 preg_replace 仅替换第一个匹配项

    我有一个结构类似于以下的字符串 aba aaa cba sbd dga gad aaa cbz 该字符串每次都可能有点不同 因为它来自外部源 我只想替换第一次出现的 aaa 但其他人则不然 是否可以 可选的第四个参数预替换 http php
  • 会话重新启动后 AVcapture 会话启动缓慢

    我有一个主视图控制器 它连接到具有 avcapturesession 的第二个视图控制器 我第一次从主视图控制器转向捕获会话控制器 大约需要 50 毫秒 使用 仪器 检查 然后我从捕获会话返回到主视图控制器 然后从主控制器返回到 avcap
  • 如何知道Matlab中系统命令执行过程中经过的时间?

    我有一个运行系统脚本的 Matlab 代码 该脚本可能会因命令运行而停止 我想知道是否有一种方法可以让程序知道它是否花费了很长时间并执行其他操作 这是代码 tic status cmdout system iperfcmd The prog
  • PHP 与 MySQL 查询性能( if 、 函数 )

    我只看到这个artice http www onextrapixel com 2010 06 23 mysql has functions part 5 php vs mysql performance 我需要知道在这种情况下什么是最好的表
  • 使用正则表达式提取两个短语之间的所有单词[重复]

    这个问题在这里已经有答案了 我正在尝试使用以下正则表达式提取两个短语之间的所有单词 b item W w W 0 2 1 one W w W 0 3 business b b item W w W 0 2 3 three W w W 0 3

随机推荐

  • 如何在 Ruby 中输出前导零?

    我正在从 Ruby 脚本输出一组编号的文件 这些数字来自递增计数器 但为了使它们在目录中很好地排序 我想在文件名中使用前导零 换句话说 文件 001 代替 file 1 有没有simple将数字转换为字符串时添加前导零的方法 我知道我可以做
  • 使用泛型和 jpa EntityManager 方法

    我可以同时使用泛型和 JPA 吗 我正在尝试将四个类的对象持久保存到我的数据库中 这是我的 PersistService 类 public class PersistService
  • 从 erlang 插入 cassandra

    我正在尝试从 Erlang R14B02 通过 thrift 0 6 1 将一些内容插入到 cassandra 0 7 6 中 我正在做以下事情 读取记录定义 rr cassandra types 连接到卡桑德拉 ok C thrift c
  • TopMost = true 的 WinForms 对话框

    我在 WinForms 中实现了一个对话框 该对话框在屏幕右下角显示为通知对话框 问题是 无论何时显示 它都会获得焦点 并且只有当 TopMost true 时才会发生这种情况 我该如何解决这个问题 您需要继承 Form 并覆盖几个属性 F
  • 每个 Docker 容器一个或多个数据库

    假设我有几个不同的容器 每个容器都使用自己的数据库 在这种情况下 关于性能的最佳实践是什么 运行一个容器 比如一台 MySQL 服务器 其中包含所有数据库 还是每个数据库运行一个数据库服务器容器 除了表演之外 任何其他评论都将受到欢迎 由于
  • Android Studio 3.1.1中Aapt2错误

    我将 android studio 从 2 2 更新到 3 1 它总是给我aapt2 error并且构建失败 我添加了android enableAapt2 false在 gradle properties 中 我的项目成功构建 但出现警告
  • Laravel 中的长轮询(sleep() 函数使应用程序冻结)

    我正在尝试在 Laravel 中编写长轮询功能 但是当我使用 sleep 函数时 整个应用程序会冻结 阻塞 直到 sleep 函数完成 有谁知道如何解决这个问题 我的 JavaScript 看起来像这样 function startRefr
  • 自托管 MVC 5 项目

    嘿 您知道如何在桌面上没有本地 IIS 或 IIS Express 的情况下运行 MVC 5 项目吗 在 ASP NET vNext 中 有一个 WebListener 使这成为可能 但我无法将我的项目重新组织为 ASP NET vNext
  • “GridView1”触发了未处理的事件 PageIndexChanging

    我正在使用 gridview 我想使用分页 我已经将允许分页设置为 true 并将页面大小设置为 5 我可以看到 gridview 底部的数字 但是当我单击数字移动到相应页面时 它会抛出错误 The GridView GridView1 f
  • Windows Batch 中嵌套循环中的“继续”等效命令

    我有一个批处理文件 其中包含嵌套循环continue类似命令 for i in 1 2 4 8 16 32 64 128 256 do for j in 1 2 4 8 16 32 64 128 256 do if i gtr j goto
  • jdk1.7/jre/lib/rt.jar的访问限制

    大家好 我在创建 JAXB 解析器时遇到了一个非常奇怪的问题 当我尝试从 eclipse 生成 JAXB 类时 在一个类中它显示了一个非常奇怪的错误 即 Access restriction The type QName is not ac
  • 无法解析 org.tensorflow:tensorflow-lite:0.0.0-nightly

    我下载了最新的tensorflow lite demo 展示一下 Unable to resolve dependency for app debug compileClasspath Could not resolve org tenso
  • 可以阻止 Django 截断长表名吗?

    我将 Django 与现有的 Oracle 数据库 即表不是由 Django 创建的数据库 一起使用 因此 在我的模型中 我必须通过在 Meta 类中指定 db table 的值来指示表名称 我遇到了问题 因为我希望访问的表属于与我拥有凭据
  • 使用多个模板显示页面内容 - WordPress

    是否可以有这样的页面 www site com page 并使用以下命令显示不同的模板版本 www site com page template default www site com page template archive 因此它检
  • C++ 联合体、结构体、成员类型

    如果我有课 class Odp int i int b union long f struct WCHAR pwszFoo HRESULT hr 联合意味着 在列出的所有值中 它一次只能采用其中一个值 就访问这些变量而言 它是如何工作的 我
  • 如何在Python中的图像上打印印地语句子(unicode)?

    我有一个名为 hindi txt 的文件 其内容如下 我使用的是Python3 5 9 59000 Cr 36 WhatsApp Allo 10 150
  • 在 Cython 中分配中间多维数组而不获取 GIL

    我正在尝试使用 Cython 并行化涉及生成中间多维数组的昂贵操作 以下非常简化的代码说明了我正在尝试做的事情 import numpy as np cimport cython cimport numpy as np from cytho
  • 从 Windows NT 设备路径转换为驱动器号路径

    如何解析设备路径中带有驱动器号的路径 例如 转换 Device HarddiskVolume4 Windows System32 RuntimeBroker exe into C Windows System32 RuntimeBroker
  • 在 xml 文件中搜索数据的最佳方法?

    在我们的新项目中 我们必须提供搜索功能来从数百个 xml 文件中检索数据 下面我简要介绍了我们目前的计划 我想知道您对此的建议 改进 这些 xml 文件包含个人信息 搜索基于其中的 10 个元素 例如姓氏 名字 电子邮件等 我们当前的计划是
  • grep -f 的性能问题

    我正在使用 grep 在单个文件中搜索多个正则表达式 特别是 我正在考虑100 MB 文件 带英文字幕 https drive google com open id 0B3oOQ14 tellNzhlU0tKT2xFSW8并运行存储在文件中