我想递归删除所有以.in
.这需要很长时间,而且我有很多可用的核心,所以我想并行化这个过程。从这个线程,看起来可以使用xargs
或make
并行化find
。 find 的这个应用程序可以并行吗?
这是我当前的串行命令:
find . -name "*.in" -type f -delete
答案1
替换-delete
为-print
(这是默认值)并通过管道传输到 GNU 并行应该可以做到这一点:
find . -name '*.in' -type f | parallel rm --
这将为每个核心运行一项作业;使用并行作业来代替-j N
。N
这是否会比按顺序删除运行得更快并不完全明显,因为删除可能更多的是 I/O 而不是 CPU 绑定,但测试一下会很有趣。
(我说“主要是这样做”是因为这两个命令并不完全等效;例如,parallel
如果某些输入路径包含换行符,该版本将不会执行正确的操作。)
答案2
替换find . -name "*.in" -type f -delete
为find . -name '*.in' -type f | parallel rm --
(或更正确的等效形式为find -print0
+ parallel -0
(或xargs -r0 -P10 -n1
))可能并不总是一个好的选择。
$ parallel -X touch {}.testfile ::: {00000..99999}
$ ls | wc -l
100000
$ time find . -name '*.testfile' -type f | parallel -j10 rm --
real 20m58.470s
user 11m30.553s
sys 58m15.265s
$ parallel -X touch {}.testfile ::: {00000..99999}
$ ls | wc -l
100000
$ time find . -name '*.testfile' -type f -delete
real 3m57.199s
user 0m0.973s
sys 0m37.356s
正如你在这里看到的顺序版本要快得多。正如其他人正确指出的那样I/O 界限是这限制因素(CPU、磁盘和内存利用率非常低),并行化只会增加一些开销(在简单的情况下)。
调整并行化选项可能会给您带来相似或更好的结果。一种开始方法是描述的选项这里。
这个有点被骗了(这里我没有find
文件,但假设我知道名字)但仍然较慢比顺序的:
$ time seq -f 'rm %04g.testfile' 00000 99999 | parallel --pipe sh
real 8m9.800s
user 2m54.668s
sys 0m57.027s