2009-06-11 3 views
6

В моем веб-приложении я обрабатываю страницы с использованием PHP-скрипта, а затем генерирую из них статические HTML-файлы. Статический HTML предоставляется пользователям для повышения производительности. HTML-файлы в конечном итоге устаревают и их необходимо удалить.Что быстрее, «найти -exec» или «найти | xargs -0 '?

Я обсуждаю между двумя способами написания сценария выселения.

Первый с помощью одной команды поиска, как

find /var/www/cache -type f -mmin +10 -exec rm \{} \; 

Вторая форма по конвейеру через xargs, что-то вроде

find /var/www/cache -type f -mmin +10 -print0 | xargs -0 rm 

Первая форма вызывает rm для каждого файла, он находит, а вторая форма просто отправляет все имена файлов в один rm (но список файлов может быть очень длинным).

Какая форма будет быстрее?

В моем случае каталог кеша разделяется между несколькими веб-серверами, поэтому все это делается по NFS, если это имеет значение для этой проблемы.

ответ

6

Я ожидаю, что версия xargs будет немного быстрее, так как вы не создаете процесс для каждого имени файла. Но я был бы удивлен, если бы на практике была большая разница. Если вас беспокоит длинный список xargs, отправляемый на каждый вызов rm, вы можете использовать -l с xargs, чтобы ограничить количество токенов, которые он будет использовать. Однако xargs знает самую длинную длину cmdline и не выходит за рамки этого.

+3

Я думаю, что xargs автоматически (без -l) порождает несколько процессов, если количество аргументов больше, чем максимальный размер оболочки. – MatthieuP

+0

Спасибо. Я не знал, что xargs могут это сделать. – yhager

13

версия xargs драматически быстрее с большим количеством файлов, чем -exec версии, как вы разместили ее, это происходит потому, что rm выполняется один раз для каждого файла вы хотите удалить, в то время как xargs будет сваливать столько файлов, как возможно вместе в одну команду rm.

С десятками или сотнями тысяч файлов это может быть разница между минутой или меньше в сравнении с большей частью часа.

Вы можете получить такое же поведение с помощью -exec, выполнив команду «+» вместо «\;». Этот параметр доступен только в более поздних версиях find.

Следующие два примерно эквивалентны:

find . -print0 | xargs -0 rm 
find . -exec rm \{} + 

Обратите внимание, что версия xargs будет по-прежнему работать немного быстрее (на несколько процентов) в системе с несколькими процессорами, потому что некоторые работы можно распараллелить. Это особенно верно, если задействовано множество вычислений.

+1

Я нашел xargs более быстрым способом. Я через первые 250 000 файлов занимаю почти два часа. Затем я наткнулся на это SO и попробовал xargs. Завершил остальные 750 000 за полчаса, как чемпион! – bbbco

+0

'-exec ...+ 'является частью стандарта POSIX для' find'; его поддержка должна быть достаточно распространенной. – chepner

2

Команда find имеет встроенную опцию -delete, возможно, она также может быть полезна? http://lists.freebsd.org/pipermail/freebsd-questions/2004-July/051768.html

+0

Ницца, спасибо. Я посмотрел на страницу руководства, и есть одно предостережение, которое следует понимать прежде, чем кто-либо захочет использовать -delete вариант с find. Я не могу вставить его здесь, но обязательно внимательно прочитайте этого человека. – yhager