Поиск текста в файлах - Самый быстрый способ?

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Аватара пользователя
BIT
новенький
Сообщения: 25
Зарегистрирован: 29.12.2017 14:44:58

Сообщение BIT »

olegy123 писал(а):
BIT писал(а):он пропускает все символы в нетипизированне файлах
?? Он не пропускает их.. он не перебирает каждый Items а читает весь Raw

Добавлено спустя 2 минуты 45 секунд:
BIT писал(а):Не файлы маленькие с текстом по несколько килобайт

тогда как измеряете скорость?там все мгновенно происходит.
Может проблема в измерениях?

Простым прогресс баром сравнивал поиск в одинаковых папках моя программа ищет примерно 1 мин а notepad++ 60 сек

Добавлено спустя 17 минут 45 секунд:
Вот сравнение поиска моя программа и нодпедом++
https://youtu.be/qniyhibgra4
pupsik
энтузиаст
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13
Контактная информация:

Сообщение pupsik »

В общем "на глаз" замеры были.

Попробуйте в вашем коде воспользоваться BeginUpdate, EndUpdate.
т.е.
не

Код: Выделить всё

FindAllFiles(PascalFiles, 'Путь до папки', '*', True);

, а

Код: Выделить всё

PascalFiles.BeginUpdate;
FindAllFiles(PascalFiles, 'Путь до папки', '*', True);
PascalFiles.EndUpdate;

Аналогичные действия с
SL.LoadFromFile(PascalFiles.Strings[f]); //Открываем файл
olegy123
долгожитель
Сообщения: 1643
Зарегистрирован: 25.02.2016 11:10:20

Сообщение olegy123 »

pupsik писал(а): TStringStream лучше заменить memorystream. Плюс уйти от pos. Но это не важно

pos разве не ассемблерная вставка?
по поводу TStringStream и memorystream - на малых файлах не так однозначно что лучше.
Аватара пользователя
BIT
новенький
Сообщения: 25
Зарегистрирован: 29.12.2017 14:44:58

Сообщение BIT »

pupsik писал(а):В общем "на глаз" замеры были.

Попробуйте в вашем коде воспользоваться BeginUpdate, EndUpdate.
т.е.
не

Код: Выделить всё

FindAllFiles(PascalFiles, 'Путь до папки', '*', True);

, а

Код: Выделить всё

PascalFiles.BeginUpdate;
FindAllFiles(PascalFiles, 'Путь до папки', '*', True);
PascalFiles.EndUpdate;

Аналогичные действия с
SL.LoadFromFile(PascalFiles.Strings[f]); //Открываем файл

Я вас понял но проблема именно в Pos Пути загружены прогресс бар отображает только начало поиска в новом файле вот видео сравнения https://youtu.be/qniyhibgra4
olegy123
долгожитель
Сообщения: 1643
Зарегистрирован: 25.02.2016 11:10:20

Сообщение olegy123 »

BIT писал(а):Простым прогресс баром сравнивал поиск в одинаковых папках моя программа ищет примерно 1 мин а notepad++ 60 сек

так это файловый поиск по папкам?
ну тогда нужно подкидывать файлы в память(TMemoryStream), там их pos-ить.
это дело можно распалить.
Аватара пользователя
BIT
новенький
Сообщения: 25
Зарегистрирован: 29.12.2017 14:44:58

Сообщение BIT »

Если можете напишите пожалуйста функцию как искать часть текст в файле использую память (поток) возможно вы все правы только я упертый думаю что все что мы обсуждаем одно и тоже?

Добавлено спустя 55 минут 28 секунд:
Вообщем нашел причину иза чего так долго ищет если при поиске не добавлять результат поиска в Synedit ищет так же быстро как и нотпед++
Теперь встал вопрос как записать данные результата.
Просто сохранять в переменную а после работы поиска выводить в synedit
Тормазить поиск так же не будет?

Вообщем все отлично вот результат --> Спасибо всем за общение)!!: Записал результат поиска на видео https://youtu.be/oJBfdDYORfg

Код: Выделить всё

Var
  PachName: string;
  SearchFileT: SearchFileThread;
  PascalFiles, SL: TStringList;
  PascalFiles_1: string;
  f, i: integer;
  flag: boolean = False;
  fileNameSearchResult: TStringList;   
.................................................

  begin
  SL := TStringList.Create;
  PascalFiles := TStringList.Create;
  fileNameSearchResult := TStringList.Create;

  FindAllFiles(PascalFiles, PachName, '*', True);

  for f := 0 to PascalFiles.Count - 1 do
  begin
    if flag then
    begin
      SL.LoadFromFile(PascalFiles.Strings[f]);   //Открываем файл
      Form3.ProgressBar1.Position := f;
      for i := 0 to SL.Count - 1 do
      begin
        if pos(UTF8LowerCase(Trim(Form3.ComboBox1.Text)),
          UTF8LowerCase(Trim(SL.Strings[i]))) > 0 then
        begin
          if Trim(PascalFiles.Strings[f]) <> Trim(PascalFiles_1) then
          begin
            fileNameSearchResult.Add('Файл| ' + PascalFiles.Strings[f]);
            PascalFiles_1 := PascalFiles.Strings[f];
          end;
          fileNameSearchResult.Add('Line ' + IntToStr(i) + ': ' + SL.Strings[i]);
        end;
      end;
end;

//Выводим результат поиска
  Form1.SynEdit1.Text := fileNameSearchResult.Text;

  end;
pupsik
энтузиаст
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13
Контактная информация:

Сообщение pupsik »

при поиске не добавлять результат поиска в Synedit
....
Я вас понял но проблема именно..
у Synedit то же есть BeginUpdate, EndUpdate. Вы явно не поняли посыл :)
Аватара пользователя
BIT
новенький
Сообщения: 25
Зарегистрирован: 29.12.2017 14:44:58

Сообщение BIT »

pupsik писал(а):
при поиске не добавлять результат поиска в Synedit
....
Я вас понял но проблема именно..
у Synedit то же есть BeginUpdate, EndUpdate. Вы явно не поняли посыл :)

Спасибо я обязательно посмотрю что это и поможет ли оно мне в данном случае)
Поменял Pos на PosEx теперь ищет текст в файле на 70% быстрей чем notepad++ вот результат https://youtu.be/IgY-cQcV7xQ
Python
новенький
Сообщения: 20
Зарегистрирован: 23.01.2018 20:50:17

Сообщение Python »

Я бы рекомендовал использовать проецирование файлов в память. Это позволит искать в файлах с размером до 2Гб не задумываясь о тонкостях чтения, а в полученном буфере уже искать любым алгоритмом. Но это решение Windows-only, для кросс-платформенного приложения не подойдёт.
Ответить