我很惊讶地发现,当您添加该--ignore-case
选项时grep
,它会使搜索速度减慢 50 倍。我已经在两台不同的机器上进行了测试,结果相同。我很想知道巨大的性能差异的解释。
我还希望看到 grep 的替代命令以进行不区分大小写的搜索。我不需要正则表达式,只需要固定字符串搜索。首先,测试文件将是一个 50 MB 的纯文本文件,其中包含一些虚拟数据,您可以使用以下代码生成它:
创建 test.txt
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 倍。
$ 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 倍。
$ time LANG=POSIX grep --ignore-case fun test.txt
all work and no plJack is no fun
Jack is no Fun
real 0m0.142s
备择方案
我们可以改用 Perl,它更快,但仍然比区分大小写的 grep 快 5.5 倍。上面的 POSIX grep 大约快两倍。
$ 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(Natty Narwhal),另一台 12.04(Precise Pangolin)。在 CentOS 5.3 机器上运行相同的测试会产生以下有趣的结果。两种情况的性能结果几乎相同。现在 CentOS 5.3 于 2009 年 1 月发布,运行 grep 2.5.1,而 Ubuntu 12.04 运行 grep 2.10。因此,新版本可能会发生变化,两个发行版可能会有所不同。
$ 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