Есть ли более быстрая альтернатива стату Perl? - PullRequest
4 голосов
/ 08 января 2010

Я перебираю весь раздел, stat() проверяю каждый файл, а затем проверяю возвращаемые значения на mtime, size и uid на соответствие хэшированным значениям. stat() однако в Perl слишком медленно, и мне интересно, есть ли какие-нибудь более быстрые альтернативы, которые я мог бы пропустить.

Ответы [ 6 ]

18 голосов
/ 08 января 2010

Когда вы звоните stat, вы запрашиваете файловую систему и будете ограничены ее производительностью. Для большого количества файлов это будет медленно; на самом деле это не проблема Perl.

8 голосов
/ 08 января 2010

Прежде чем вы приступите к оптимизации stat , используйте Devel :: NYTProf , чтобы увидеть реальное замедление.

Также изучите детали того, как вы смонтировали файловую систему. Все локально, или вы смонтировали что-то поверх NFS или что-то подобное? Есть много вещей, которые могут быть проблемой, как указали другие ответы. Не тратьте слишком много времени на то, чтобы сосредоточиться на любой потенциальной проблеме, пока не узнаете, что это проблема.

Удачи,

6 голосов
/ 08 января 2010

Вы видели, что stat достаточно медленный, поэтому не вызывайте его более одного раза для одного и того же файла.

Документация perlfunc для -X (операторы тестирования файла shell-ish) описывает хороший кеш для stat:

Если какой-либо из файловых тестов (или операторов stat или lstat) получает специальный файловый дескриптор, состоящий из одиночного подчеркивания, то используется структура статистики предыдущего теста файла (или оператор статистики) сохранение системного вызова. (Это не работает с -t, и вам нужно помнить, что lstat и -l оставят значения в структуре статистики для символической ссылки, а не для реального файла.) (Кроме того, если буфер статистики был заполненные вызовом lstat, -T и -B сбросят его с результатами stat _). Пример: * +1021 *

print "Can do.\n" if -r $a || -w _ || -x _;
stat($filename);
print "Readable\n" if -r _;
print "Writable\n" if -w _;
print "Executable\n" if -x _;
print "Setuid\n" if -u _;
print "Setgid\n" if -g _;
print "Sticky\n" if -k _;
print "Text\n" if -T _;
print "Binary\n" if -B _;
6 голосов
/ 08 января 2010

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

Если вы неоднократно stat определяете один и тот же файл (-ы), рассмотрите возможность использования Memoize.

use Memoize();

sub fileStat {
  my ($filename) = @_;
  return stat($filename);
}

Memoize::memoize('fileStat');
0 голосов
/ 08 января 2010

Рассмотрим Файл :: Найти модуль.

0 голосов
/ 08 января 2010
  • Если вы используете * NIX, вы можете просто использовать ls и проанализировать вывод, я должен подумать.
  • Как упоминал Эфир, find, возможно, является хорошей альтернативой, если вы просто хотите принять решение о том, что вы считаете.
  • Но размер, дата и uid должны быть доступны из ls output.
  • Хотя дата и размер доступны из команды dir на платформе Windows.
...