Когда вы запускаете ls
без аргументов, он просто открывает каталог, читает все содержимое, сортирует их и распечатывает.
Когда вы запускаете ls *
, сначала расширяется оболочка *
, которая, по сути, такая же, как и простая ls
, создает вектор аргумента со всеми файлами в текущем каталоге и вызовами ls
. ls
затем должен обработать этот вектор аргумента и для каждого аргумента и access(2)
вызвать файл, чтобы проверить его существование. Затем он выведет тот же вывод, что и первый (простой) ls
. Обработка оболочкой большого вектора аргумента и аргументов ls
, вероятно, потребует большого объема памяти, выделяемой маленьким блокам, что может занять некоторое время. Однако, так как там было мало sys
и user
времени, но много real
времени, большую часть времени были бы потрачены в ожидании диска, а не с помощью процессора делает выделение памяти.
Каждый вызов должен access(2)
будет прочитать inode файла, чтобы получить информацию о разрешениях. Это означает, что гораздо больше операций чтения и поиска на диске, чем просто чтение каталога. Я не знаю, насколько дорогими являются эти операции в вашей GPFS, но, как показывает сравнение, время выполнения ls -l
которого аналогично случаю с подстановочными знаками, время, необходимое для получения информации об индексах, кажется доминирующим. Если GPFS имеет немного большую задержку, чем ваша локальная файловая система при каждой операции чтения, мы ожидаем, что она будет более выраженной в этих случаях.
Разницу между регистром подстановки и ls -l
50% можно объяснить порядком расположения inode на диске. Если иноды были расположены в том же порядке, что и имена файлов в каталоге, и 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
которой можно просто спросить файловую систему "для чего нужны дочерние узлы inodepwd
", где как сls *
он должен спросить «каковы дочерние элементы (и что это за файл) в inodea
», а затем b, c, d и т. д. и т. д. Один запрос против многих.ls -l
(все еще примерно на 30 секунд меньшеls *
)ls -l
Потребуется больше времени, чемls
требуется дляstat(2)
каждого файла*
всплывающие окна со всеми записями в текущем каталоге, которые не начинаются с точки, включая имена подкаталогов. Что тогда будетls
« под ред.ls
<ls -l
<ls -l *
<ls *
(я всегда пытался это трижды). С твоим объяснением я не понимаю, почемуls -l *
это быстрее, чемls *