Целевой каталог содержит 10 million+ текстовых файлов. using $a = scandir()
на веб-странице смертельно медленное. Требуется массив результатов менее чем за две секунды. Фильтрация не работает (также просматривает весь список)
все, что я могу придумать, это использовать программу perl
или c
для предварительной обработки и заполнения x тысяч имен файлов из целевого каталога в файл, пометить имена файлов в целевом каталоге, выбранном с помощью .pi
в конце (или что-то), и использовать php file()
чтобы получить список из файла.
Мне нужно открыть и работать с каждым файлом, прежде чем он будет забит в таблицу. FYI. Я не могу дождаться более 1-2 секунд, чтобы массив работал, чтобы быть доступным. Любая помощь была оценена. Память не является проблемой. hdd
пространство не является проблемой, мощность процессора не является проблемой. проблема заключается в получении списка в массиве Fast при использовании интерфейса веб-страницы. Я не могу ждать, потому что я устал ждать.
Я попытался использовать краткую быструю программу c с opendir
и readdir
но даже для сканирования списка каталогов требуется почти 4 минуты. по крайней мере, я мог бы поставить на него губернатора, чтобы ограничить файлы x.
Кажется, что ответ заключается в вызове программы perl
или c
которую я могу ограничить файлами x, и я могу назвать это с помощью system()
или backticks
. Затем этот список можно открыть с помощью file()
... OTF... имеет смысл?
Проблема в том, что меньше 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
. Это уменьшит количество файлов в одном каталоге до уровня, который может лучше обрабатывать файловая система.
Вы можете написать программу на языке C
которая вызывает getdents
getdents. Используйте большой размер буфера, например 5 МБ, и пропустите записи с inode == 0, чтобы значительно повысить производительность.
Решения, которые полагаются на libc
readdir()
, медленны, потому что они ограничены чтением 32K кусков записей в каталоге за раз.
Этот подход описан в блоге Olark Developers Corner, приведенном ниже.
Рекомендации:
scandir()
реализован в C - это не будет иметь большого значения).