c — scandir () в PHP слишком медленный

Целевой каталог содержит более 10 миллионов текстовых файлов. using $a = scandir() на веб-странице смертельно медленно. Нужно получить массив результатов менее чем за две секунды. Фильтрация не работает (сканирует весь список тоже)

все, что я могу думать, это использовать perl или же c запрограммируйте предварительную обработку и поместите x тысяч имен файлов из целевого каталога в файл, отметьте имена файлов в целевом каталоге, выбранном с помощью .pi в конце (или что-то) и использовать PHP file() функция, чтобы получить список из файла вместо этого.

Мне нужно открыть и работать с каждым файлом, прежде чем он будет помещен в таблицу. FYI. Я не могу ждать более 1-2 секунд, пока массив не будет доступен.
Любая помощь приветствуется. Память не проблема. hdd пространство не является проблемой, мощность процессора не является проблемой. проблема заключается в получении списка в массиве Fast при использовании внешнего интерфейса веб-страницы. Я не могу ждать, потому что я устал ждать.

Я попытался с помощью короткой быстрой программы с opendir а также readdir но даже сканирование списка каталогов занимает почти 4 минуты. по крайней мере, я мог бы поставить на него губернатор, чтобы ограничить х файлов.

Кажется, ответ заключается в том, чтобы позвонить perl или же c программа, которую я могу ограничить х файлов, и я могу назвать это с system() или же backticks, Затем этот список можно открыть с помощью file()… OTF … имеет смысл?

0

Решение

Проблема заключается не столько в PHP, сколько в файловой системе. Большинство файловых систем плохо работают с 10 миллионами файлов в одном каталоге, и производительность начинает сильно снижаться. Вы вряд ли получите гораздо лучшую производительность от переписывания его в C или Perl, потому что файловая система просто перегружена, а ее производительность стала патологической.

Сначала переключитесь с scandir в opendir а также readdir. Это позволяет избежать создания массива из 10 миллионов элементов. Это также позволяет вашей программе начать работу непосредственно перед тем, как кропотливо прочитать 10 миллионов имен файлов.

if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
...do your work...
}
closedir($dh);
}

Во-вторых, реструктурируйте свой каталог, чтобы иметь как минимум два уровня подкаталогов на основе первых букв имен файлов. Например, t/h/this.is.an.example, Это сократит количество файлов в одном каталоге до уровня, который файловая система сможет лучше обрабатывать.

7

Другие решения

Вы можете написать C программа, которая вызывает getdents Системный вызов. Используйте большой размер буфера, скажем, 5 МБ, и пропускайте записи с индексом == 0, чтобы значительно повысить производительность.

Решения, основанные на libc readdir() медленные, потому что они ограничены чтением 32K фрагментов записей каталога за раз.

Этот подход описан в блоге Olark Developers Corner, ссылки на который приведены ниже.

Рекомендации:

3

По вопросам рекламы [email protected]