Дмитрий Шурупов
			
				написал 12 апреля 2004 года в 18:39 (1110 просмотров)
			
			
			Ведет себя
			 как фрик; открыл 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 декабря 2023 года в 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
        
  
DevOps as a Service from Palark
	24/7 SRE & DevOps service to cover all your Kubernetes needs.

Идея есть одна, да и та — тупая.. :))
Переложить поиск на то, что этим лучше умеет заниматься — на *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, секунды (это с учетом подсчета и выставления приоритетов в соответствии с релевантностью, а также дальнейшей сортировки результатов). Вполне прилично, меня устраивает.