我写了一些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
对性能的影响将重要。这似乎仍然失控。
答案 0 :(得分:1)
xargs将为它处理的每一行调用一个新进程,因此在你的情况下,它会旋转5802次,并在系列中执行此操作
您可以尝试parallel
您可能正在使用xargs来调用计算密集型命令 每一行输入。如果xargs允许你采取不是很好 您机器中多核的优势?那就是-P 对于。它允许xargs多次调用指定的命令 平行。例如,您可以使用它来运行多个ffmpeg 并行编码。不过我只是想给你看另一个 人为的例子。
或者另一方面,您可以使用sed来轻松旋转
答案 1 :(得分:0)
好吧,我的根本误解是假设最大命令行长度在2000范围内。所以我假设每20个文件左右一个perl实例(每个大约120个字符)。这非常不正确。
getconf ARG_MAX
显示实际可接受的长度。就我而言:
2097152
所以,我正在查看1个perl实例与5802个实例。我能想到的唯一的perl解决方案是删除-n
并手动实现循环,显式关闭每个文件。
我认为更好的解决方案是awk:
find . -name '*.cpp' 2>/dev/null -print0 | xargs -0 awk '{if (/\+\+\S*[cC]ursor\S*/ && !/[!=]=\s*DB_NULL_CURSOR/) {print FILENAME ":" FNR " " $0}}'
或grep:
find . -name '*.cpp' 2>/dev/null -print0 | xargs -0 grep -nE '\+\+\S*[cC]ursor\S*' | grep -v '[!=]=\s*DB_NULL_CURSOR'
两者都在2或3秒范围内执行。