find
为了递归遍历目录的内容,似乎必须检查给定的路径是否对应于文件或目录。
这是一些动机,也是我在当地所做的,使自己确信自己find . -type f
确实比慢find .
。我还没有深入研究GNU查找源代码。
因此,我要备份$HOME/Workspace
目录中的某些文件,并排除属于我的项目或版本控制文件的文件。
因此,我运行了以下命令,该命令快速执行
% find Workspace/ | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > ws-files-and-dirs.txt
find
用管道传递到grep
可能是错误的形式,但这似乎是使用否定的正则表达式过滤器的最直接方法。
以下命令仅在find输出中包含文件,并且花费的时间明显更长。
% find Workspace/ -type f | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > ws-files-only.txt
我编写了一些代码来测试这两个命令的性能(使用dash
和tcsh
,以排除shell可能产生的任何影响,即使不应有任何影响)。的tcsh
,因为他们基本上是相同的结果已被忽略。
我得到的结果表明,该产品的性能损失约为10% -type f
这是程序的输出,显示了执行各种命令的1000次迭代所花费的时间。
% perl tester.pl
/bin/sh -c find Workspace/ >/dev/null
82.986582
/bin/sh -c find Workspace/ | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > /dev/null
90.313318
/bin/sh -c find Workspace/ -type f >/dev/null
102.882118
/bin/sh -c find Workspace/ -type f | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > /dev/null
109.872865
经过测试
% find --version
find (GNU findutils) 4.4.2
Copyright (C) 2007 Free Software Foundation, Inc.
在Ubuntu 15.10上
这是我用于基准测试的perl脚本
#!/usr/bin/env perl
use strict;
use warnings;
use Time::HiRes qw[gettimeofday tv_interval];
my $max_iterations = 1000;
my $find_everything_no_grep = <<'EOF';
find Workspace/ >/dev/null
EOF
my $find_everything = <<'EOF';
find Workspace/ | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > /dev/null
EOF
my $find_just_file_no_grep = <<'EOF';
find Workspace/ -type f >/dev/null
EOF
my $find_just_file = <<'EOF';
find Workspace/ -type f | grep -v '/vendor\|/node_modules/\|Workspace/sources/\|/venv/\|/.git/' > /dev/null
EOF
my @finds = ($find_everything_no_grep, $find_everything,
$find_just_file_no_grep, $find_just_file);
sub time_command {
my @args = @_;
my $start = [gettimeofday()];
for my $x (1 .. $max_iterations) {
system(@args);
}
return tv_interval($start);
}
for my $shell (["/bin/sh", '-c']) {
for my $command (@finds) {
print "@$shell $command";
printf "%s\n\n", time_command(@$shell, $command);
}
}
-type f
选项导致find
调用stat()
或fstat()
或任何以找出是否该文件名对应一个文件,目录,符号链接,等等等等我做了strace
一个find .
和find . -type f
和跟踪几乎相同,仅在write()
其中具有目录名称的调用中有所不同。所以,我不知道,但是我想知道答案。
time
内置命令可以查看命令执行所需的时间,您实际上不需要编写自定义脚本来进行测试。
find
为了递归遍历目录的内容,似乎必须检查给定的路径是否对应于文件或目录。-它必须检查它是否是目录,而不必检查它是否是文件。还有其他条目类型:命名管道,符号链接,阻止特殊设备,套接字...因此,尽管它可能已经进行了检查以查看它是否为目录,但这并不意味着它知道它是否为常规文件。