Коли ви запустите ls
без аргументів, він просто відкриє каталог, прочитає весь вміст, відсортує їх і роздрукує.
Під час запуску ls *
спочатку оболонка розширюється *
, що фактично те саме, що ls
робив простий , будує вектор аргументу з усіма файлами в поточному каталозі та викликає ls
. ls
потім має обробити цей вектор аргументу та для кожного аргументу та викликає access(2)
¹ файл, щоб перевірити його існування. Тоді він виведе той самий вихід, що і перший (простий) ls
. Як оболонка, обробка великого вектора аргументів, так і ls
s, ймовірно, буде мати багато виділення в пам'яті невеликих блоків, що може зайняти деякий час. Однак, так як там було мало sys
і user
часу, але багато real
часу, більшу частину часу були б витрачені в очікуванні диска, а не з допомогою процесора робить виділення пам'яті.
Кожен виклик потрібно access(2)
буде прочитати вкладення файлу, щоб отримати інформацію про дозвіл. Це означає, що набагато більше читає і шукає диск, ніж просто читати каталог. Я не знаю, як дорого коштують ці операції на вашій GPFS, але в порівнянні, яке ви показали, ls -l
який має аналогічний час запуску із символом підстановки, час, необхідний для отримання інформації про вклад, домінує. Якщо GPFS має дещо більшу затримку, ніж ваша локальна файлова система на кожній операції читання, ми очікуємо, що в цих випадках вона буде більш вираженою.
Різниця між шаблоном підстановки та ls -l
50% може бути пояснена впорядкуванням входів на диску. Якби вставки були викладені послідовно в тому ж порядку, як імена файлів у каталозі та ls -l
stat (2) редагували файли в порядку каталогу перед сортуванням, ls -l
можливо, прочитали б більшість індексів під час розгортки. За допомогою шаблону підказки оболонка буде сортувати імена файлів, перш ніж передавати їх ls
, тому ls
, ймовірно, читатиме вкладиші в іншому порядку, додаючи більше руху головки диска.
Слід зауважити, що ваш time
результат не буде включати час, витрачений оболонкою на розширення підстановки.
Якщо ви дійсно хочете побачити, що відбувається, скористайтеся strace(1)
:
strace -o /tmp/ls-star.trace ls *
strace -o /tmp/ls-l-star.trace ls -l *
і подивіться, які системні дзвінки виконуються в кожному конкретному випадку.
¹ Я не знаю, чи access(2)
насправді використовується, чи щось інше на зразок stat(2)
. Але обом, ймовірно, потрібен пошук inode (я не впевнений, чи access(file, 0)
не обійшов би пошук inode.)
ls
ним можна просто запитати у файловій системі "для чого діти вводуpwd
", де як зls *
він повинен запитати "які діти (і який файл) inodea
", а потім b, c, d тощо. Один запит проти багатьох.