最快的速度

我想知道是否有任何提示,使 grep尽快。我有一个相当大的文本文件的基础,以最快的方式搜索。我把它们都设置成小写,这样我就可以去掉 -i选项。这使得搜索速度大大加快。

另外,我发现 -F-P模式比默认模式更快。如果搜索字符串不是正则表达式(只是纯文本) ,则使用前者,如果涉及正则表达式,则使用后者。

有人有加速 grep的经验吗?也许从头开始用某个特定的标志(我在 Linux CentOS 上)编译它,以某种方式组织文件,或者以某种方式使搜索并行?

91667 次浏览

尝试使用 GNU 并行,其中包括 如何与 grep一起使用它的示例:

grep -r递归地通过目录进行抓取 parallel通常可以加速这一过程。

find . -type f | parallel -k -j150% -n 1000 -m grep -H -n STRING {}

每个核将运行1.5个作业,并为 grep提供1000个参数。

对于大文件,它可以使用 --pipe--block参数将输入分成几个块:

 parallel --pipe --block 2M grep foo < bigfile

您还可以通过 SSH (避免密码所需的 SSH-agent)在几台不同的机器上运行它:

parallel --pipe --sshlogin server.example.com,server2.example.net grep foo < bigfile

严格来说,这并不是一个代码改进,但是在对2 + 00万个文件运行 grep 之后,我发现了一些有用的东西。

我把操作转移到一个便宜的固态硬盘(120GB)上。大约100美元,如果你经常处理大量的文件,这是一个负担得起的选择。

如果您正在搜索非常大的文件,那么设置您的区域设置可能真的有帮助。

GNU grep 在 C 语言环境中比在 UTF-8中快得多。

export LC_ALL=C

显然,使用—— mmap 可以在某些系统上提供帮助:

Http://lists.freebsd.org/pipermail/freebsd-current/2010-august/019310.html

Cgrep,如果可用的话,可以比 grep 数量级更快。

MCE 1.508包含一个支持许多 C 二进制文件的双块级别{ file,list }包装器脚本;。

Https://metacpan.org/source/marioroy/mce-1.509/bin/mce_grep

Https://metacpan.org/release/mce

当需要-i 快速运行时,不需要转换为小写。只需将—— lang = C 传递给 mce _ grep 即可。

输出顺序保留。N 和-b 输出也是正确的。不幸的是,本页中提到的 GNU 并行并不是这种情况。我真的希望 GNU 并行在这里工作。另外,mce _ grep 在调用二进制文件时执行 没有子 shell (sh-c/path/to/grep)。

另一种替代方法是 MCE 中包含的 MCE: : Grep 模块。

在 Sandro 的响应的基础上,我查看了他提供的 给你引用,并使用了 BSD grep 和 GNU grep。我的快速基准测试结果显示: GNUgrep 非常非常快。

因此,我对最初的问题“最快可能的 grep”的建议是: 确保您使用的是 GNU grep 而不是 BSD grep (例如,这是 MacOS 上的默认设置)。

如果您不关心哪些文件包含字符串,您可能希望将 阅读抢劫分成两个作业,因为多次产生 grep的代价可能很高——每个小文件产生一次。

  1. 如果你有一个很大的文件:

    parallel -j100% --pipepart --block 100M -a <very large SEEKABLE file> grep <...>

  2. 许多小的压缩文件(按 inode 排序)

    ls -i | sort -n | cut -d' ' -f2 | fgrep \.gz | parallel -j80% --group "gzcat {}" | parallel -j50% --pipe --round-robin -u -N1000 grep <..>

我通常用 lz4压缩文件以获得最大吞吐量。

  1. 如果只想要匹配的文件名:

    ls -i | sort -n | cut -d' ' -f2 | fgrep \.gz | parallel -j100% --group "gzcat {} | grep -lq <..> && echo {}

我个人使用 ag (silver searcher)代替 grep,它的速度更快,你也可以将它与并行和管道块组合在一起。

Https://github.com/ggreer/the_silver_searcher

更新: 我现在使用 https://github.com/BurntSushi/ripgrep,它比农业快,这取决于你的用例。

我发现使用 grep 在单个大文件中搜索(特别是在更改模式时)更快的一个方法是使用 split + grep + xargs 和它的并行标志。例如:

在一个名为 my _ ids. txt 的大文件中搜索 id 文件 Bigfile bigfile.txt 的名称

使用分割将文件分割为多个部分:

# Use split to split the file into x number of files, consider your big file
# size and try to stay under 26 split files to keep the filenames
# easy from split (xa[a-z]), in my example I have 10 million rows in bigfile
split -l 1000000 bigfile.txt
# Produces output files named xa[a-t]


# Now use split files + xargs to iterate and launch parallel greps with output
for id in $(cat my_ids.txt) ; do ls xa* | xargs -n 1 -P 20 grep $id >> matches.txt ; done
# Here you can tune your parallel greps with -P, in my case I am being greedy
# Also be aware that there's no point in allocating more greps than x files

在我的案例中,这将原本17小时的工作变成了1小时20分钟的工作。我确信这里有一些关于效率的钟形曲线,显然重温可用的核心不会给你带来任何好处,但是这是一个比上面的任何评论更好的解决方案。与脚本并行相比,这在使用大多数(linux)本机工具方面有一个额外的好处。

Ripgrep 声称现在是最快的。

Https://github.com/burntsushi/ripgrep

默认情况下还包括并行性

 -j, --threads ARG
The number of threads to use.  Defaults to the number of logical CPUs (capped at 6).  [default: 0]

来自 README

它构建在 Rust 的正则表达式引擎之上 有限自动机,SIMD 和积极的文字优化作出 快速搜索。

与最初的主题略有不同: 来自 googledesearch 项目的索引搜索命令行实用程序比 grep: https://github.com/google/codesearch快得多:

一旦你编译了它(需要 Golang包) ,你可以索引一个文件夹:

# index current folder
cindex .

索引将在 ~/.csearchindex下创建

现在你可以搜索:

# search folders previously indexed with cindex
csearch eggs

我仍然通过 grep 管道输入结果以获得彩色匹配。