Команда 'ls' очень медленная

386
tytywin

У меня есть около 17k файлов в каталоге. Когда я бегу ls directory, мне нужно подождать около 15-20 секунд, прежде чем отобразятся результаты. С другой стороны, когда я запускаю ls directory | wc -lили ls directory | grep .xyz, результаты отображаются сразу.

Почему это происходит и есть ли способ это исправить?

0
Это происходит потому, что в каталоге 17k файлов. Решение состоит в том, чтобы в каталоге было меньше файлов. Ignacio Vazquez-Abrams 6 лет назад 1
печать на консоль всегда медленная. OTOH, передавая данные через канал, оставит вывод в памяти или файле, так что это будет намного быстрее phuclv 6 лет назад 0
Эта проблема связана с буфером отображения (?) Консоли. «Медлительность» происходит из-за вывода данных через буфер, а не самой команды. confetti 6 лет назад 0
@ IgnacioVazquez-Abrams, что если вы инженер ML? tytywin 6 лет назад 0
Я бы нашел лучший способ организовать данные. Ignacio Vazquez-Abrams 6 лет назад 0

2 ответа на вопрос

2
grawity

Я собираюсь догадаться, что вы используете Linux.

  1. Если ваша lsкоманда имеет псевдоним, такой, что она показывает файлы и папки в цвете, то ей необходимо выяснить права доступа каждого элемента (вызов stat ()) и определить, установлены ли у них какие-либо «возможности файла» (вызов getxattr ()). выбрать правильный цвет. В зависимости от файловой системы эти вызовы могут быть довольно медленными, если необходимые метаданные еще не были кэшированы в ОЗУ. [Расширенные атрибуты часто находятся в области данных, поэтому каждый getxattr приводит к поиску жесткого диска.]

    С другой стороны, ls |при перенаправлении в канал автоматически отключается окрашивание, поэтому ему больше не нужно выполнять никаких дополнительных проверок - просто простой цикл readdir (), который возвращает имя и тип файла, и ядро, вероятно, даже реализует упреждающее чтение для тот.

  2. Обычно lsколонки выводят, что означает, что он должен прочитать весь каталог, прежде чем он сможет что-либо выводить вообще. При запуске через канал он автоматически отключает режим столбцов, и эта буферизация больше не требуется. (Общее время выполнения не обязательно быстрее, но вывод начинается раньше, что делает его более отзывчивым.)

Используйте straceили, perf traceчтобы проверить, какие системные вызовы, если они есть, занимают много времени.

0
Kamil Maciorowski

Две вещи:

  1. Если вы запускаете lsсначала и ls | wc -lпозже, возможно, что первое будет считываться с вашего жесткого диска, а второе будет считывать кэшированные данные. Если это так, то lsизначально «глохнет» и ничего не печатает в течение нескольких секунд. Другой lsначнет печатать почти сразу, пока кэшированные данные все еще там. Если вы начали с ls | wc -lсамого начала, то пришлось бы ждать, пока жесткий диск предоставит данные.
  2. Любой терминал работает со своей скоростью. Формально stty speedпокажет вам некоторую ценность, но я думаю, что это не имеет значения для виртуального терминала. Тем не менее, отображение символов и прокрутка занимает много времени (см. Этот вопрос ). Передача тех же данных через канал происходит быстрее.