Есть ли более быстрая альтернатива статистике Perl?

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


person Wally    schedule 07.01.2010    source источник
comment
Зачем ты это делаешь? Я спрашиваю, потому что это пахнет работой для rsync или хорошим инструментом для резервного копирования.   -  person Schwern    schedule 08.01.2010
comment
Покажите нам свой код - статистика сама по себе не медленная.   -  person    schedule 08.01.2010
comment
Если ввод-вывод вашей файловой системы является вашим узким местом и вам нужно быстрее, вы можете рассмотреть аппаратные решения, в том числе больше ОЗУ для кеш-памяти вашей файловой системы, RAID-массивы и твердотельные накопители (в частности, новейшие SLC от Intel могут абсолютно ).   -  person    schedule 08.01.2010


Ответы (6)


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

person Michael Carman    schedule 07.01.2010
comment
Это лучший ответ. stat () - это системный вызов unix, а одноименная функция perl - всего лишь (очень тонкая!) обертка вокруг него. Если он медленный, он медленный из-за необходимого дискового ввода-вывода, и это не то, что вы можете исправить. - person Andy Ross; 08.01.2010

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

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

Удачи,

person brian d foy    schedule 07.01.2010

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

Если вы неоднократно stat загружаете одни и те же файлы, подумайте об использовании Memoize.

use Memoize();

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

Memoize::memoize('fileStat');
person mopoke    schedule 07.01.2010
comment
использовать memoize не обязательно. просто сделайте @array = stat ($ file) и получите из него значения. - person ; 08.01.2010
comment
Memoize будет сохранять все возвращаемые значения каждый раз, когда вы вызываете fileStat, а не только один вызов stat. Да, вы можете создать свой собственный кеш для всех вызовов возврата статистики, но зачем это делать, когда Memoize делает это за вас? - person mopoke; 08.01.2010
comment
Однако многократное указание одних и тех же файлов будет происходить из кеша файловой системы и, таким образом, будет не так медленно, как дисковая производительность, которую плакат видит при обходе всей файловой системы. Я сильно подозреваю, что Memoize здесь ни к чему. - person Andy Ross; 08.01.2010
comment
Поскольку Memoize поможет вам создать огромный кеш (гигабайты, если у вас есть оперативная память), на самом деле он поможет не только кеш-памятью файловой системы. Однако какая польза от кеша, если вы ищете последние изменения. Использование Memoize может быть не очень хорошей идеей, потому что это будет зависеть от сценария использования плаката. - person harschware; 08.01.2010

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

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

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

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 _;
person Greg Bacon    schedule 07.01.2010

Рассмотрим модуль File :: Find.

person harschware    schedule 07.01.2010

  • Если вы используете * NIX, вы можете просто использовать ls и анализировать вывод, я думаю.
  • Как упоминалось в эфире, find, возможно, является хорошей альтернативой, если вы просто хотите принимать решения о том, что вы показываете.
  • Но размер, дата и uid должны быть доступны из ls вывода.
  • Дата и размер доступны с помощью команды dir на платформе Windows.
person Axeman    schedule 07.01.2010
comment
В UNIX / Linux ls и find также будут использовать stat системный вызов через метод библиотеки C. Если эти подходы улучшают производительность, то это не из-за stat как такового. - person Stephen C; 08.01.2010
comment
@Stephen C: Хотя он мог бы вызывать stat более эффективно. Я не знаю. - person Axeman; 08.01.2010
comment
Ответ является умозрительным и не показывает никаких усилий со стороны отвечающего. - person daxim; 08.01.2010