2010-01-07 6 views
4

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

+2

Зачем вы это делаете?Я прошу, потому что он пахнет работой для rsync или хорошим инструментом резервного копирования. – Schwern

+4

Покажите нам свой код - стат сам по себе ** не ** медленно. – 2010-01-07 21:19:37

+1

Если ваша файловая система IO ** является вашим узким местом, и вам это нужно быстрее, вы можете рассмотреть аппаратные решения, в том числе больше оперативной памяти для вашего кеша файловой системы, массивов RAID и SSD (самые новые SLC от Intel, в частности, могут абсолютно кнутом). – fennec

ответ

6

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

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

use Memoize(); 

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

Memoize::memoize('fileStat'); 
+1

используя memoize не требуется. просто сделайте @array = stat ($ file) и получите от него значения. – 2010-01-07 21:18:57

+2

Memoize будет хранить все возвращаемые значения каждый раз, когда вы вызываете fileStat, а не только один вызов stat. Да, вы можете создать свой собственный кеш для всех вызовов возврата stat, но зачем это делать, когда Memoize делает это за вас? – mopoke

+0

Неоднократно указывая одни и те же файлы, будет делать это из кеша файловой системы и, следовательно, будет не так медленным, как производительность, связанная с диском, которую плакат видит в обход всей файловой системы. Я сильно подозреваю, что Memoize не принесет пользы. –

17

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

+5

Это лучший ответ. «stat()» является системным вызовом unix, а функция perl с тем же именем - это просто (очень тонкая!) оболочка вокруг него. Если он медленный, он медленный из-за требуемого дискового ввода-вывода, и это не то, что вы можете исправить. –

-3
  • Если вы на * NIX, вы можете просто использовать ls и проанализировать вывод, я должен подумать.
  • Как упоминалось в эфире, find, возможно, является хорошей альтернативой, если вы просто хотите принять решение о том, что вы статируете.
  • Но размер, дата и uid должны быть доступны с ls.
  • Пока дата и размер доступны из команды dir на платформе Windows.
+3

В UNIX/Linux 'ls' и' find' также будут использовать syscall 'stat' через библиотечный метод C. Если эти подходы улучшают производительность, это происходит не из-за 'stat' * per se *. –

+0

@Stephen C: Он мог бы более эффективно использовать 'stat'. Я не знаю. – Axeman

+1

Ответ является умозрительным и не прилагает никаких усилий от имени ответчика. – daxim

8

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

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

Успехов,

6

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

perlfunc documentation on -X (в скорлупе иш операторов тестовых файлов) описывает хороший кэш для stat:

Если какой-либо из тестов файл (или либо stat или lstat операторов) дается специальный дескриптор файла, состоящий из одиночная подчеркивание, тогда используется структура stat предыдущего теста файла (или оператора статистики), сохраняя системный вызов. (Это не работает с -t, и вам нужно помнить, что lstat и -l оставят значения в структуре stat для символической ссылки, а не реального файла.) (Кроме того, если буфер статистики был заполнен вызовом 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 _; 
Смежные вопросы