Kiedy biegniesz ls
bez argumentów, po prostu otworzy katalog, przeczyta całą zawartość, posortuje je i wydrukuje.
Po uruchomieniu ls *
najpierw powłoka rozszerza się *
, co w rzeczywistości jest tym samym, co proste ls
, buduje wektor argumentów ze wszystkimi plikami w bieżącym katalogu i wywołaniami ls
. ls
następnie musi przetworzyć ten wektor argumentów i dla każdego argumentu i wywołuje access(2)
¹ plik, aby sprawdzić jego istnienie. Następnie wydrukuje to samo wyjście, co pierwsze (proste) ls
. Zarówno przetwarzanie przez duży wektor argumentów, jak i proces powłoki ls
będą prawdopodobnie wymagać dużej alokacji pamięci małych bloków, co może zająć trochę czasu. Jednak, ponieważ nie było mało sys
i user
czasu, ale dużo real
czasu, większość czasu byłaby spędził czekając na dysku, zamiast CPU robi alokacji pamięci.
Każde wywołanie access(2)
będzie musiało przeczytać i-węzeł pliku, aby uzyskać informacje o uprawnieniach. Oznacza to, że o wiele więcej dysków czyta i szuka niż tylko czytanie katalogu. Nie wiem, jak drogie są te operacje na twoim systemie GPFS, ale ponieważ pokazane porównanie, ls -l
które ma podobny czas działania do przypadku wieloznacznego, wydaje się, że czas potrzebny na odzyskanie informacji i-węzłowych wydaje się dominować. Jeśli GPFS ma nieco większe opóźnienie niż lokalny system plików podczas każdej operacji odczytu, spodziewalibyśmy się, że w tych przypadkach będzie bardziej wyraźny.
Różnicę między wielkością wieloznaczną a ls -l
50% można wyjaśnić uporządkowaniem i-węzłów na dysku. Gdyby i-węzły były ułożone kolejno w tej samej kolejności, co nazwy plików w katalogu, a ls -l
stat (2) edował pliki w kolejności katalogów przed sortowaniem, ls -l
prawdopodobnie odczytałby większość i-węzłów podczas przeciągnięcia. Za pomocą symbolu wieloznacznego powłoka posortuje nazwy plików przed przekazaniem ich ls
, więc ls
prawdopodobnie odczyta i-węzły w innej kolejności, zwiększając ruch głowicy dysku.
Należy zauważyć, że twój time
wynik nie będzie zawierał czasu potrzebnego powłoce na rozwinięcie symbolu wieloznacznego.
Jeśli naprawdę chcesz zobaczyć, co się dzieje, użyj strace(1)
:
strace -o /tmp/ls-star.trace ls *
strace -o /tmp/ls-l-star.trace ls -l *
i zobacz, które wywołania systemowe są wykonywane w każdym przypadku.
¹ Nie wiem, czy access(2)
jest rzeczywiście używany, czy coś takiego jak stat(2)
. Ale oba prawdopodobnie wymagają wyszukiwania i-węzłów (nie jestem pewien, czy access(file, 0)
pominie to wyszukiwanie i-węzłów).
ls
czemu może po prostu zapytać system plików „po co są dzieci i-węzłapwd
” gdziels *
musi zapytać „jakie są dzieci (i jaki jest plik) i-węzłaa
”, a następnie b, c, d itd. itd. Jedno zapytanie vs. wiele.