nixp.ru v3.0

22 октября 2017,
воскресенье,
20:36:38 MSK

DevOps с компанией «Флант»
Аватар пользователя Дмитрий Шурупов
Дмитрий Шурупов написал 12 апреля 2004 года в 18:39 (506 просмотров) Ведет себя как фрик; открыл 670 тем в форуме, оставил 5692 комментария на сайте.

Ладно, ну с этой индексацией. Работает нормально.

Лучше посоветуйте: как-нибудь можно оптимизировать поиск по файлам? Язык программирования — 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);
}

Идеи?

Genie

Идея есть одна, да и та — тупая.. :))

Переложить поиск на то, что этим лучше умеет заниматься — на *sql, к примеру..

Либо… мммм..

тут есть у тебя алгоритмическая ошибка. или как там.

логично, что слова для поиска задаются в том порядке, в котором они ожидаются?

тогда не надо делать цикл — не надо инкрементировать $prior.

строишь PREx из шаблона (типа спросили «file+name», выражение тогда «/(file)?.*(name)?/») и разбиваешь имя файла в массив по этому выражению. считаешь его. автоматом получается твоё $prior.

Дмитрий Шурупов

>> тут есть у тебя алгоритмическая ошибка. или как там.

Если ищут, например, moby+harbour, то сначала он у меня выведет точно соответствие (именно ту песню которую искали), а потом не совсем точное, которое может быть полезно, если кто-то не так назвал файл/директорию на сервере, спрашивающий не совсем правильно составил свой запрос (опечатался/не знает точного названия). В общем, так куда правильнее, это точно. Да и времени это отнимает не очень много. Куда больше отнимает процесс поиска вообще.

anonymous

А если все хранить в DBM-файлах и в них же кэшировать запросы… Да и хотя бы просто к твоему алгоритму кэширование добавить и он уже быстрее станет )))

Дмитрий Шурупов

Кэширование уже сделал.

А алгоритм перекроил. Сделал действительно по совету Genie: если набрали «moby+harbour», то ничего кроме этой песни в результатах пусть и не ждут :)) Стало полегче…

Дмитрий Шурупов

Докопался до истины. Проблема в моем левом sub ucru.

use locale; use POSIX qw(locale_h); setlocale(LC_CTYPE,«ru_RU.CP1251»);

И родной uc(); (уже с поддержкой русского) позволил ускорить процесс поиска в разы (вызывался-то &ucru тысячи раз…).

anonymous

Тогда еще увеличить быстродействие может бинарный поиск. То есть, сортируешь файл, открываешь его, переходишь на середину(sysseek`ом), чиатешь строку(главное учти что далеко не факт что ты попадешь в начало строки после sysseek, то есть для верности лучше прочитать две строчики, тогда вторая будет точно полной), сравниваешь больше или меньше(по алфавиту) строка из файла и искомая, в завсисимости от этого делешь какую-то из половин на два и читаешь оттуда, так до тех пор, пока не найдешь искомую строку или не замкнешься на одной.

Дмитрий Шурупов

Так ведь проблема в том, что искомое может находиться в любом месте строки. Т.е. соответствующим запросу может стать как первый в пути каталог, так и промежуточный каталог (где-то в середине path’а), так и файл в конце строки.

Дмитрий Шурупов

Но вообще сейчас после массовых мелочных оптимизаций поиск по 10-мегабайтной базе проходит за 2, максимум — 3, секунды (это с учетом подсчета и выставления приоритетов в соответствии с релевантностью, а также дальнейшей сортировки результатов). Вполне прилично, меня устраивает.