내 디렉터리에 여러 파일이 있습니다.
$ ls | wc -l
9376
ls *
and를 사용할 때 왜 이렇게 큰 시차가 발생하는지 설명할 수 있는 사람이 있나요 ls
?
$ time ls > /dev/null
real 0m0.118s
user 0m0.106s
sys 0m0.011s
그리고
$ time ls * > /dev/null
real 1m32.602s
user 0m0.233s
sys 0m0.438s
좋습니다. 이는 과감한 예이며 디렉터리가 GPFS(일반 병렬 파일 시스템)에 있으므로 향상될 수 있습니다. 그러나 로컬 파일 시스템에서도 상당한 속도 저하를 볼 수 있습니다.
편집하다:
$ time ls -l > /dev/null
real 0m58.772s
user 0m0.113s
sys 0m0.452s
$ time ls -l * > /dev/null
real 1m19.538s
user 0m0.252s
sys 0m0.461s
내 예에는 하위 디렉터리가 없다는 점을 추가해야 합니다.
$ diff <(ls) <(ls *)
$
답변1
인수 없이 실행 하면 ls
디렉토리를 열고 모든 내용을 읽고 정렬하고 인쇄합니다.
를 실행하면 ls *
먼저 쉘이 확장됩니다 . 이는 단순히 현재 디렉토리의 모든 파일을 사용하여 인수 벡터를 구축하고 를 호출하는 *
것과 같습니다 . 그런 다음 해당 인수 벡터와 각 인수를 처리하고 파일을 호출하여 확인해야 합니다. 그것은 존재합니다. 그런 다음 첫 번째(간단한) 출력과 동일한 출력을 인쇄합니다 . 쉘의 큰 인수 벡터 및 합계 처리에는 많은 수의 작은 메모리 블록 할당이 포함될 수 있으며 이는 시간이 걸릴 수 있습니다. 하지만 시간이 적고 많기 때문에 메모리 할당을 위해 CPU를 사용하기 보다는 디스크를 기다리는 데 대부분의 시간을 소비하게 됩니다.ls
ls
ls
access(2)
ls
ls
sys
user
real
각 호출에서는 access(2)
권한 정보를 얻기 위해 파일의 inode를 읽어야 합니다. 이는 단순히 디렉토리를 읽는 것보다 더 많은 디스크 읽기 및 탐색을 의미합니다. GPFS에서 이러한 작업의 비용이 얼마나 드는지는 모르겠지만 ls -l
와일드카드 사례와 유사한 런타임 비교를 통해 표시한 것처럼 inode 정보를 검색하는 데 필요한 시간이 지배적인 것 같습니다. GPFS가 로컬 파일 시스템보다 읽기 작업당 대기 시간이 약간 더 길면 이러한 경우 대기 시간이 더 눈에 띌 것으로 예상됩니다.
와일드카드 케이스와 50% ls -l
의 차이는 디스크의 inode 순서로 설명할 수 있습니다. inode를 디렉토리에 있는 파일 이름과 동일한 순서로 연속적으로 배열하고 ls -l
파일을 디렉토리 순서대로 stat(2)한 후 정렬한 경우 ls -l
한 번의 스캔으로 대부분의 inode를 읽을 수 있습니다. 와일드카드를 사용하면 쉘이 파일 이름을 전달하기 전에 정렬하므로 ls
inode ls
를 다른 순서로 읽을 수 있어 디스크 헤드 이동이 더 많아집니다.
출력 에는 time
쉘 확장 와일드카드에 소요된 시간이 포함되지 않습니다.
무슨 일이 일어나고 있는지 정말로 알고 싶다면 다음을 사용하십시오 strace(1)
.
strace -o /tmp/ls-star.trace ls *
strace -o /tmp/ls-l-star.trace ls -l *
각 경우에 어떤 시스템 호출이 실행되고 있는지 확인하세요.
access(2)
¹ 그것이 실제로 사용되는지, 아니면 다른 것인지는 알 수 없습니다 . 예를 들어 둘 다 inode 조회가 필요할 수 있습니다( inode 조회를 우회할지 stat(2)
여부는 확실하지 않습니다 .)access(file, 0)