【发布时间】:2018-06-02 13:17:27
【问题描述】:
我写了一点 perl 单行:
find . -name '*.cpp' -print0 2>/dev/null | xargs -0 -i perl -ne 'if (/\+\+\S*[cC]ursor\S*/ && !/[!=]=\s*DB_NULL_CURSOR/) {print "$ARGV:$.\n $_\n";}' {}
在我运行它的目录中,find 部分返回 5802 个结果。
现在,我知道xargs -i(或-n1)会对性能产生影响,但-i:
find . -name '*.cpp' -print0 2> /dev/null 0.33s user 1.12s system 0% cpu 3:12.57 total
xargs -0 -i perl -ne {} 4.12s user 32.80s system 16% cpu 3:42.22 total
没有:
find . -name '*.cpp' -print0 2> /dev/null 0.27s user 1.22s system 95% cpu 1.556 total
xargs -0 perl -ne 0.62s user 0.69s system 61% cpu 2.117 total
几分钟与几秒钟(确认测试顺序无关紧要)。除了在第二个实例中明显不正确的行号之外,实际的 perl 结果是相同的。
Cygwin/bash/perl5v26 和 WSL Ubuntu 16.04/zsh/perl5v22 中的行为相同。在这两种情况下,文件系统都是 NTFS。但是...我有点假设我写的那个小单行字一定有某种错误,而那些东西是无关紧要的?
编辑:我突然想到在启动时使用-f 禁用sitecustomize.pl --一个我隐约记得使用perl --help 看到的选项可能会有所帮助。它没。另外,我知道由于 perl 编译正则表达式,-i 的性能影响将是显着。这似乎仍然失控。
【问题讨论】:
-
您不需要 xargs 或并行,您只需要直接通过管道传输到 perl,如果它们符合您的正则表达式规则,它将遍历您的文件名并打印它们。
-
甚至
find ... -exec perl -ne '...' {} +也可以避开管道。 -
@xxfelixxx 没有 xargs,您必须在 perl 中打开文件,并且由于
-print0,您不会逐行获取它们。也许最好简单地使用带有File::Find的perl脚本@ -
所以它需要 55 倍的时间,但你产生的数量会增加 100 倍到 8000 倍
perl解释器... -
@tripleee,虽然您可以通过使用
-exec而不是-print0来避免xargs,但-exec ;的性能应该类似于xargs -n 1(并且-exec +的性能应该类似于@987654340 @ 没有-n 1)。