我需要运行grep
几百万个文件。因此我尝试加快速度,遵循这里提到的两种方法:xargs -P -n
和GNU parallel
。我在我的文件子集(数量为 9026)上尝试了此操作,结果如下:
与
xargs -P 8 -n 1000
,非常快:$ time find tex -maxdepth 1 -name "*.json" | \ xargs -P 8 -n 1000 grep -ohP "'pattern'" > /dev/null real 0m0.085s user 0m0.333s sys 0m0.058s
使用
parallel
,非常慢:$ time find tex -maxdepth 1 -name "*.json" | \ parallel -j 8 grep -ohP "'pattern'" > /dev/null real 0m21.566s user 0m22.021s sys 0m18.505s
即使顺序也
xargs
比parallel
:$ time find tex -maxdepth 1 -name "*.json" | \ xargs grep -ohP 'pattern' > /dev/null real 0m0.242s user 0m0.209s sys 0m0.040s
xargs -P n
对我来说不起作用,因为所有进程的输出都会交错,而parallel
.所以我想parallel
在不造成这种巨大的减速的情况下使用。
有任何想法吗?
更新
继奥莱·坦格的回答,我尝试过
parallel -X
,结果在这里,为了完整性:$ time find tex -maxdepth 1 -name "*.json" | \ parallel -X -j 8 grep -ohP "'pattern'" > /dev/null real 0m0.563s user 0m0.583s sys 0m0.110s
最快的解决方案:继@cas 的评论,我尝试使用 grep
-H
选项(强制打印文件名)并排序。结果在这里:time find tex -maxdepth 1 -name '*.json' -print0 | \ xargs -0r -P 9 -n 500 grep --line-buffered -oHP 'pattern' | \ sort -t: -k1 | cut -d: -f2- > /dev/null real 0m0.144s user 0m0.417s sys 0m0.095s
答案1
尝试parallel -X
。正如评论中所写,启动新 shell 并打开文件以缓冲每个参数的开销可能是原因。
请注意,GNU Parallel 永远不会像 xargs 一样快,因此。预计每个作业的开销为 10 毫秒。使用 -X 时,当您在一项作业中处理更多参数时,这种开销就不那么重要了。