首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么"grep -忽略-案例“慢50倍?

为什么"grep -忽略-案例“慢50倍?
EN

Stack Overflow用户
提问于 2012-12-11 11:41:54
回答 4查看 3.7K关注 0票数 15

我很惊讶地看到,当您将--ignore-case选项添加到grep中时,它可以将搜索速度降低50倍。我在两台不同的机器上测试过,结果是一样的。我很想找出一个巨大的性能差异的解释。

我还想看到一个代替grep的命令,用于不区分大小写的搜索。我不需要正则表达式,只需要固定的字符串搜索。首先,测试文件将是一个带有一些虚拟数据的50 MB纯文本文件,您可以使用以下代码来生成它:

创建test.txt

代码语言:javascript
复制
yes all work and no play makes Jack a dull boy | head -c 50M > test.txt
echo "Jack is no fun" >> test.txt
echo "Jack is no Fun" >> test.txt

演示

下面是一个缓慢的演示。通过添加--ignore-case选项,命令速度将慢57倍。

代码语言:javascript
复制
$ time grep fun test.txt
all work and no plJack is no fun
real    0m0.061s

$ time grep --ignore-case fun test.txt
all work and no plJack is no fun
Jack is no Fun
real    0m3.498s

可能的解释

在搜索周围,我发现了一个关于grep在UTF-8环境中速度慢的讨论。所以我运行了下面的测试,它确实加快了速度。我的机器上的默认区域设置是en_US.UTF-8,因此将其设置为POSIX似乎已经启动了性能,但是现在我当然不能正确地搜索Unicode文本,这是不可取的。它的速度仍然慢了2.5倍。

代码语言:javascript
复制
$ time LANG=POSIX grep --ignore-case fun test.txt
all work and no plJack is no fun
Jack is no Fun
real    0m0.142s

Alternatives

我们可以使用Perl代替它更快,但仍然比区分大小写的grep快5.5倍。而上面的POSIX大约是速度的两倍。

代码语言:javascript
复制
$ time perl -ne '/fun/i && print' test.txt
all work and no plJack is no fun
Jack is no Fun
real    0m0.388s

所以我想找到一个快速正确的替代方案,如果有人有解释的话。

更新- CentOS

上面测试的两台机器都在运行Ubuntu --一台11.04 ( Narwhal),另一台12.04 (精确穿山甲)。在CentOS 5.3计算机上运行相同的测试会产生以下有趣的结果。两种情况的性能结果基本一致。现在,CentOS 5.3于2009年1月发布,an运行grep2.5.1,Ubuntu12.04运行grep2.10。因此,新版本可能会发生变化,这两个发行版之间可能会有差异。

代码语言:javascript
复制
$ time grep fun test.txt
Jack is no fun
real    0m0.026s

$ time grep --ignore-case fun test.txt
Jack is no fun
Jack is no Fun
real    0m0.027s
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-12-11 12:01:16

我认为这个bug报告有助于理解为什么它是缓慢的:

错误报告grep,忽略时慢慢来

票数 8
EN

Stack Overflow用户

发布于 2013-01-09 13:44:47

这是由于grep (在UTF-8语言环境上)经常访问文件“/usr/lib/locale/locale-归档”和“/usr/lib/gconv/gconv-Modes.cache”。

它可以使用绞合实用程序显示。这两个文件都来自glibc。

票数 8
EN

Stack Overflow用户

发布于 2016-11-25 18:16:15

原因是它需要对当前的地区做一个Unicode感知的比较,从Marat的回答来看,这样做的效率不高。

这表明,当没有考虑Unicode时,它的速度要快得多:

代码语言:javascript
复制
$ time LC_CTYPE=C grep -i fun test.txt
all work and no plJack is no fun
Jack is no Fun
real    0m0.192s

当然,这种替代方法不能与其他语言的字符一起使用,例如: in / and、Of /、/and、/and/等。

另一种选择是修改regex,使其与大小写不敏感匹配:

代码语言:javascript
复制
$ time grep '[Ff][Uu][Nn]' test.txt
all work and no plJack is no fun
Jack is no Fun
real    0m0.193s

这是相当快的,但当然,将每个字符转换为一个类是很痛苦的,并且不太容易将其转换为别名或sh脚本,这与上面的脚本不同。

比较而言,在我的系统中:

代码语言:javascript
复制
$ time grep fun test.txt
all work and no plJack is no fun
real    0m0.085s

$ time grep -i fun test.txt
all work and no plJack is no fun
Jack is no Fun
real    0m3.810s
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13819635

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档