Дмитрий Шурупов
написал 12 апреля 2004 года в 18:39 (998 просмотров)
Ведет себя
как фрик; открыл 670 тем в форуме, оставил 5727 комментариев на сайте.
Ладно, ну с этой индексацией. Работает нормально.
Лучше посоветуйте: как-нибудь можно оптимизировать поиск по файлам? Язык программирования — Perl. Файлы суммарно составляют объем в 10--15 мб plain/text.m Их формат:
первая_строка_с_разной_информацией_о_сервере
Каталог1|0
Файл1|123
Файл2|1234
Каталог2|0
Каталог3|0
…
Ищем с поддержкой «+» и «*». У меня это происходит тупым перебором (способа лучше придумать не могу):
### файл с базой сервера ### проверяем, не найдено ли уже слишком много совпадений if (open(SERV,"$datadir/$server.data") && $total<$maximum){ ### забираем первую строку файла chomp($file=); while($file=){ ### каждый раз проверяем на переполнение (наверное, это лучше убрать) if ($total<$maximum){ ### еще будем искать приоритет совпадения chomp($file); $prior=0; ### здесь начинаем перебор всех слов в запросе, заданных через "+" (или " ") foreach $stmp(@stmpa){ chomp($file); @fileinfo=split(/\|/,$file); ### делаем название файла/каталог большим; @stmpa уже такое $fileinfo[0]=&ucru($fileinfo[0]); if ("$fileinfo[0]" =~ /$stmp/){ $prior+=10; $prior+=10 while($'=~/$stmp/); } } if ($prior){ push(@results,"$prior|$server|$file"); $total++; } } } close(SERV); }
Идеи?
Последние комментарии
- OlegL, 17 декабря в 15:00 → Перекличка 21
- REDkiy, 8 июня 2023 года в 9:09 → Как «замокать» файл для юниттеста в Python? 2
- fhunter, 29 ноября 2022 года в 2:09 → Проблема с NO_PUBKEY: как получить GPG-ключ и добавить его в базу apt? 6
- Иванн, 9 апреля 2022 года в 8:31 → Ассоциация РАСПО провела первое учредительное собрание 1
- Kiri11.ADV1, 7 марта 2021 года в 12:01 → Логи catalina.out в TomCat 9 в формате JSON 1
ecobeing.ru
Экология и вегетарианство на благо всем живым существам Планеты.
Идея есть одна, да и та — тупая.. :))
Переложить поиск на то, что этим лучше умеет заниматься — на *sql, к примеру..
Либо… мммм..
тут есть у тебя алгоритмическая ошибка. или как там.
логично, что слова для поиска задаются в том порядке, в котором они ожидаются?
тогда не надо делать цикл — не надо инкрементировать $prior.
строишь PREx из шаблона (типа спросили «file+name», выражение тогда «/(file)?.*(name)?/») и разбиваешь имя файла в массив по этому выражению. считаешь его. автоматом получается твоё $prior.
>> тут есть у тебя алгоритмическая ошибка. или как там.
Если ищут, например, moby+harbour, то сначала он у меня выведет точно соответствие (именно ту песню которую искали), а потом не совсем точное, которое может быть полезно, если кто-то не так назвал файл/директорию на сервере, спрашивающий не совсем правильно составил свой запрос (опечатался/не знает точного названия). В общем, так куда правильнее, это точно. Да и времени это отнимает не очень много. Куда больше отнимает процесс поиска вообще.
А если все хранить в DBM-файлах и в них же кэшировать запросы… Да и хотя бы просто к твоему алгоритму кэширование добавить и он уже быстрее станет )))
Кэширование уже сделал.
А алгоритм перекроил. Сделал действительно по совету Genie: если набрали «moby+harbour», то ничего кроме этой песни в результатах пусть и не ждут :)) Стало полегче…
Докопался до истины. Проблема в моем левом sub ucru.
use locale; use POSIX qw(locale_h); setlocale(LC_CTYPE,«ru_RU.CP1251»);
И родной uc(); (уже с поддержкой русского) позволил ускорить процесс поиска в разы (вызывался-то &ucru тысячи раз…).
Тогда еще увеличить быстродействие может бинарный поиск. То есть, сортируешь файл, открываешь его, переходишь на середину(sysseek`ом), чиатешь строку(главное учти что далеко не факт что ты попадешь в начало строки после sysseek, то есть для верности лучше прочитать две строчики, тогда вторая будет точно полной), сравниваешь больше или меньше(по алфавиту) строка из файла и искомая, в завсисимости от этого делешь какую-то из половин на два и читаешь оттуда, так до тех пор, пока не найдешь искомую строку или не замкнешься на одной.
Так ведь проблема в том, что искомое может находиться в любом месте строки. Т.е. соответствующим запросу может стать как первый в пути каталог, так и промежуточный каталог (где-то в середине path’а), так и файл в конце строки.
Но вообще сейчас после массовых мелочных оптимизаций поиск по 10-мегабайтной базе проходит за 2, максимум — 3, секунды (это с учетом подсчета и выставления приоритетов в соответствии с релевантностью, а также дальнейшей сортировки результатов). Вполне прилично, меня устраивает.