为什么 'grep -i' 这么慢?如何让 ASCII 运行得更快?

为什么 'grep -i' 这么慢?如何让 ASCII 运行得更快?

考虑:

$ time lzop -d < tvtropes-index.lzo | egrep -B 5 '[Dd][eE][sS][cC][eE][nN][dD] ?[Ff][rR][oO][mM]'
real    0m0.438s

$ time lzop -d < tvtropes-index.lzo | egrep -B 5 'descend ?from' -i
real    0m11.294s

两者都不区分大小写地搜索。为什么这个-i版本这么慢?如何grep -i在不输入类似[iI][nN] [tT][hH][iI][sS] [wW][aA][Yy]?的内容的情况下加快速度?

例如,

perl -ne 'print if /descend ?from/i'

运行速度很快,但是 '-B 5' 的实现并不像 grep(以及其他选项)那么简单。

答案1

折叠表壳很困难

对于大多数简单的纯 ASCII 文本文档,只需将 [az] 映射到 [AZ] 即可。但是,当我们探索使用其他字符的语言时,这种方法开始失效。它也没有考虑到某些语言中的大小写映射并不总是算法或静态的这一事实。

例如,如果将 [az] -> [AZ] 折叠,则“Dürst”或“résumé”之类的字符串最终可能看起来有点奇怪:“DüRST”或“RéSUMé”。

您可以通过让 grep 再次相信世界是 ASCII 来加快速度,方法是使用古老的 grep 或通过使用语言环境(LC_ALL=C?)。

这次对话提到“UTF8 语言环境的速度大幅下降”但没有帮助。

答案2

假设

这些违反直觉的结果可以用以下公式来解释。您的正则表达式与不同,grep -i因为grep -i它更通用,考虑到复杂的多字节字符串处理,至少在使用预处理器符号编译时是这样MBS_SUPPORT

请看这里:

http://cvs.savannah.gnu.org/viewvc/grep/grep/src/search.c?revision=1.42&view=markup

寻找match_icaseMBS_SUPPORT

答案3

如果 find 的实际情况并不重要,您可以在之前使用tr折叠。[A-Z][a-z]grep

相关内容