find
디렉토리의 내용을 재귀 적으로 걸기 위해 주어진 경로가 파일이나 디렉토리에 해당하는지 확인 해야하는 것처럼 보입니다 .
여기 약간의 동기 부여와 내가 find . -type f
실제로 느리다는 것을 확신시키기 위해 로컬에서 한 일 이 find .
있습니다. GNU find 소스 코드를 아직 찾지 못했습니다.
그래서 나는 $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
그냥가 안하더라도, 쉘이있을 수있는 효과를 배제하기 위해,). 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.
우분투 15.10에서
벤치마킹에 사용한 펄 스크립트는 다음과 같습니다.
#!/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
없이 동시에 실행 됩니다. 그러나 처음에 리눅스 커널은 그것을 캐시에로드했고 처음 발견은 느렸다.
-type f
옵션을 야기 find
전화 stat()
또는 fstat()
파일 이름이 파일에 해당 여부를 확인하기 위해 또는 어떤 순서로, 등 등 내가했던 디렉토리, 심볼릭 링크 strace
A의 find .
과 find . -type f
및 추적이 거의 동일했다, write()
디렉토리 이름이 있는 호출 에서만 다릅니다 . 그래서 나는 모른다. 그러나 나는 대답을 알고 싶다.
time
명령 실행 시간을 확인하는 기본 제공 명령이 있으므로 테스트를 위해 사용자 지정 스크립트를 작성할 필요가 없습니다.
find
디렉토리의 내용을 재귀 적으로 걸기 위해 주어진 경로가 파일이나 디렉토리에 해당하는지 확인 해야하는 것처럼 보입니다 . -디렉토리인지 확인해야하며 파일인지 여부를 확인할 필요가 없습니다. 명명 된 파이프, 심볼릭 링크, 블록 특수 장치, 소켓 등의 다른 항목 유형이 있습니다. 따라서 디렉토리인지 확인하기 위해 이미 검사를 수행 했음에도 불구하고 이것이 일반 파일인지 아는 것은 아닙니다.