호출의 매개변수 순서가 find
결과 속도에 어떤 영향을 미치나요?
예를 들어 (A)를 비교하십시오.
find -name dir -type d
그리고 (B)
find -type d -name dir
또는 다른 매개변수 조합(예: -or
또는 사용 -and
). 나는 find
어떤 면에서든 똑똑해지고 싶다.
time
A와 B를 5번 반복하여 통계를 수집 해 보았습니다 . 그러나
11.86, 7.23, 5.25, 5.87, 7.16
A와 B의 경우:
9.73, 6.56, 8.69, 7.14, 6.35
이는 실제로 결론이 아니며 두 가지 모두의 평균이 곧 다가오고 7.5s
차이가 상당히 높습니다.
제 질문을 다시 말씀드리자면, 매개변수의 순서가 중요한가요 find
?
답변1
비용이 많이 드는 것은 파일에 대한 시스템 호출을 수행하는 것입니다(시스템 호출 자체와 I/O 모두에 대해).
-type
같은 것에는 파일에 대한 시스템 호출이 -mtime
필요합니다 . ,, 하지 마십시오(물론 내용 을 읽기 위해 포함된 디렉터리에 대해 시스템 호출을 수행하지만).lstat(2)
-name
-path
-regex
일반적으로 이는 어쨌든 find
실행되지만 lstat()
(해당 정보가 에 제공되지 않는 한, 파일에 들어가려면 파일이 디렉토리인지 여부를 알아야 하기 때문입니다 readdir()
), 어떤 경우에는 디렉토리 없이도 작동할 수 있습니다. 예를 들어, 디렉토리에 3개 미만의 링크가 있는 경우 일부 파일 시스템에서는 find
하위 디렉토리가 없는 것으로 알려져 있으며 일부 find
구현 lstat
에서는 s를 수행하지 않음으로써 최적화합니다.
-xtype
stat(2)
, , , , , 로 이어질 -printf ...
수 있습니다 .-ls
stat()
lstat()
readlink()
-lname
lstat()
readlink()
그렇기 때문에 아마도 -name
// ... -path
를 -regex
먼저 입력하고 싶을 것입니다. 파일을 제외할 수 있으면 하나 이상의 시스템 호출을 피할 수 있습니다.
이제 a는 -regex
a보다 더 비쌀 수 있지만 -name
교환하면 얼마를 받을 수 있을지 잘 모르겠습니다.
또한 일부 find
구현(예: GNU) 에서는 find
가능한 경우 기본적으로 검사 순서를 변경합니다. 바라보다:
info find 'Optimisation Options'
GNU 시스템(gnu.org에서 사용 가능최신 버전의 GNU의 경우 findutils
).
일반적으로 GNU 시스템에서 테스트하는 경우 두 명령 모두 동일한 작업을 수행합니다. 어쨌든 앞으로 나아갈 것이기 때문 find
입니다 -name
.
따라서 -type d -name ...
vs가 -name ... -type d
작동 하려면 find
이러한 조건자를 재정렬하여 최적화하지 않는 구현과 lstat()
모든 파일에 대해 수행하지 않고 일부 최적화를 수행하는 구현이 필요합니다.
구현에 관계없이 (큰) 차이점이 있습니다.
find . -name 'x*' -exec test -d {} \; -print
비교:
find . -exec test -d {} \; -name 'x*' -print
find
-exec
순서를 바꾸면 기능적 차이가 발생할 수 있으므로 순서를 변경할 수 없습니다 ( find
실행된 명령이 단지 테스트용인지 또는 다른 작업을 수행하기 위한 것인지 알 수 있는 방법이 없습니다).
물론 이는 -exec ... {} \;
프로세스를 분기하고 프로세스에서 명령을 실행하며(자체적으로 많은 시스템 호출을 실행함) 프로세스와 종료 코드를 기다리는 것을 의미하기 때문에 다른 조건자보다 훨씬 더 비쌉니다.
$ time find /usr/lib -exec test -d {} \; -name z\* -print > /dev/null
1.03s user 12.52s system 21% cpu 1:03.43 total
$ time find /usr/lib -name z\* -exec test -d {} \; -print > /dev/null
0.09s user 0.14s system 62% cpu 0.367 total
(첫 번째는 (56685) test
의 모든 파일이 필요하고 /usr/lib
, 두 번째는 z
이름이 (147)로 시작하는 파일만 필요합니다.)
-exec test -d {} \;
와 같지 않으니 주의하시기 바랍니다 -type d
. 이는 GNU 전용 휴대용 버전입니다 -xtype d
.