![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Поиск записей (строк,значений) в файловой базе.
Arsenija © (2006-11-29 11:19:00)Ребята нужен совет по работе с файлами.
Задача:
Имеется "исходный" текстовый файл вида:
произвольный заголовок
12345 1234567890 123 1234 12345678
...
...
54321 0234567891 321 4321 99999999
(около 10тыс записей)
имеется некая база из таких файлов. Нужно в этой базе найти повторы (к примеру значения второго столбца).
Реализация:
Моя прога берет исходный файл, формирует массив значений, которые ищем. Далее ищет в выбранном каталоге файлы с нужным расширением открывает их (Assignfile(), Reset(), Readln(,), Closefile()) И начинает построчно обрабатывать. При этом используется либо функция POS(подстрока из массива, считанная из файла строка)-вариант1, либо ищется вторая запись отделенная пробелами и проверяется длина записи-вариант2.
Вывод:
Не устраивает время работы-долго.При реализации варианта2 - 300файлов(200мегов) обрабатывает около 13 минут. Вариант 1 - вообще тупит по черному. Аналогичная функция поиска в TotalComander работает на порядок быстрее.
Внимание вопрос:
Какие есть варианты ускорения поиска?
Anatoly Podgoretsky (2006-11-29 15:10:00) [21]> Arsenija (29.11.2006 14:50:18) [18]
Это значит, что есть строки и более 8 кб по размеру, что тут не понятно русским языком.
А ты утверждаешь, что строки свыше 255 байт не бывают.
Arsenija (2006-11-29 14:50:00) [22]
> Анализ логов показывает наличие строк свыше 8 кб
Не понял, это как?
Arsenija (2006-11-29 14:45:00) [23]
> В огороде бузина, а в Киеве дядька.
> Гадание на кофейной гуще.
> Что значет "заложена" ? В ломбард что ли ?)
> Или таки "декларация переменной" ?)
Лирику в сторону
> > прорабатываем на предмет дублирования
> Подозреваю, что у тебя и здесь "узкое" место с т.з. эффективности/производительности
> алгоритма той самой "проработки"
Тоже так думал, поэтому и упростил "проработку" до минимума. Просто сравнивал строку (целиком) считанную из файла и строку(целиком) исходного файла. Результат есть, но всеравно непростительно долго.
Поэтому и родилась мысль, о том что виновата именно построчная обработка файла.
Anatoly Podgoretsky (2006-11-29 14:38:00) [24]> Arsenija (29.11.2006 14:27:13) [13]
Анализ логов показывает наличие строк свыше 8 кб
> Но это все лирика.
Это не лирика, это называется гораздо хуже.
Arsenija (2006-11-29 14:35:00) [25]
> Алгоритм такой:
> Файл любым способом всасывается в память целиком.
> Критерий раздела записей - два символа CRLF
> Критерий второй колонки - поиск первого пробела и до второго.
> > Получаем текущее поле.
> > Поля записываются в хэш-таблицу или массив уникальных.
> Перед занесением предварительно ищется вхождение, если найдено
> - повтор.
> >
Что-то похожее я и реализовал, затык на скорости обработки. Если проводить чтение и анализ каждой строки файла из базы - скажем так построчный метод, то получется неприемлимо долго. Поэтому прошу посоветовать дельное что-нить. Возможно на предмет (8)- Фантазии из [5]
Сергей М. (2006-11-29 14:33:00) [26]
> Размер string около 2 гб - это если есть нулевой символ
> в конце. Иначе 255 байт
В огороде бузина, а в Киеве дядька.
> длиннее наверняка не будет
Гадание на кофейной гуще.
> у меня строка заложена как стринг(короткий)
Что значет "заложена" ? В ломбард что ли ?)
Или таки "декларация переменной" ?)
> прорабатываем на предмет дублирования
Подозреваю, что у тебя и здесь "узкое" место с т.з. эффективности/производительности алгоритма той самой "проработки"
Arsenija (2006-11-29 14:27:00) [27]Ребята,
1 - привязка к 255 байт - длиннее наверняка не будет (string на фиг, просто у меня строка заложена как стринг(короткий))
2 - массив искомых значений :
есть исходный файл (описание вверху)
Моя прога берет исходный файл, формирует массив значений, которые ищем. Получаем массив искомых значений, каждое значение которого и прорабатываем на предмет дублирования.
З.Ы.
Anatoly Podgoretsky
Размер string около 2 гб - это если есть нулевой символ в конце. Иначе 255 байт. Но это все лирика.
Anatoly Podgoretsky (2006-11-29 14:11:00) [28]> Arsenija (29.11.2006 13:15:09) [9]
Размер string около 2 гб
Сергей М. (2006-11-29 13:27:00) [29]
> средний размер около 500кб
Понятно.
Мелочь, одним словом)
> массива искомых значений
Еще раз подробней про это:
Что за массив такой ? Откуда он взялся в связи с "в этой базе найти повторы" (цитата) ?
Jeer (2006-11-29 13:22:00) [30]Алгоритм такой:
Файл любым способом всасывается в память целиком.
Критерий раздела записей - два символа CRLF
Критерий второй колонки - поиск первого пробела и до второго.
Получаем текущее поле.
Поля записываются в хэш-таблицу или массив уникальных.
Перед занесением предварительно ищется вхождение, если найдено - повтор.
> размером string
Тебе виднее, но бывают и длинные строки.
Arsenija (2006-11-29 13:15:00) [31]Jeer
кстати если уж на то пошло, то формально можно ограничить длину строки 255 байтами - размером string
Arsenija (2006-11-29 13:12:00) [32]Сергей М.
средний размер около 500кб (максимальный на текущий день такой же)
Jeer
на начальный пример опираться не надо
реальный пример вот:
111111111111111 2222222222222222222 333333333333
или так
111111111111111 2222222222222222222 3333 44444444 5555 66666666 77777777777777777777777777777777 8888 99999999
или так
1111111111111 2222222222222222222 3333 44444444 5555 66666666 77777777777777777777777777777777 8888 99999999
TFileStream упоминул в связи с чем ? Попробовал применить TMemoryStream, но заткнулся на процедуре вычленения нужных даных для сравнения да и сама процедура поиска не вытанцовывается.
Jeer (2006-11-29 12:52:00) [33]TFileStream
Длина записи около 36 байт + 10 тыс записей = 0.360 Mбайт
Приемлимо.
Сергей М. (2006-11-29 12:50:00) [34]Каков максимальный размер подобного файла в составе "базы" ?
Arsenija (2006-11-29 12:37:00) [35]1- Смещение второго поля не фиксированное (поэтому ищутся разделители(пробелы)
2- Кол-во строк заголовка - не фиксированное
3- TotalComander имеет функцию поиска (find) в содержании файла заданного(ручками) фрагмента. Т.е. получается мы можем искать в файловой базе только одну запись. Хотелось бы проверять на дублирование сразу все(10тыс)
4- 300файлов(200мегов) это примерно десятая часть всей базы, и ее выцепил для тестирования, при обработке всей базы система впадает в печаль.
5- 13 мин - это много, 13 умножаем на 10 - получаем чуть более 2ч. Нереально много. В течении дня таких процедур может быть достаточно много (до 20-40).
6 - создавать собственную базу этих номеров (записей) и постоянно ее обновлять - это изменение технологии обработки данных - неприемлимо ( еще несколько причин). Поэтому нужно опираться на существующую файловую базу.
7 - актуально только название файла, в котором происходит совпадение (если будут выводиться и совпадающие номера - то это будет предел мечтаний), поэтому при первом совпадении обработка файла прекращается и его название выводится в поле Memo.
8 - Фантазирую: считать весь файл (не построчно) и как в обычном текстовом редакторе пробежаться поиском на предмет дублирования массива искомых значений. Но даст ли это выигрыш по времени или нет, и реализацию процесса я не представляю.
Сергей М. (2006-11-29 11:45:00) [36]
> обрабатывает около 13 минут
А куда спешить ? Что, эти 300файлов(200мегов) куда-то испарятся, если ты не успеешь их обработать менее чем за 13 минут ?
Поясни вот этот момент...
Anatoly Podgoretsky (2006-11-29 11:40:00) [37]И что там есть поиск дубликатов во втором столбце?
clickmaker (2006-11-29 11:37:00) [38]
> Аналогичная функция поиска в TotalComander работает на порядок
> быстрее
там, скорей всего, используется что-то типа CompareMem()
Сергей М. (2006-11-29 11:36:00) [39]
> Аналогичная функция поиска в TotalComander работает на порядок
> быстрее
Нет там аналогичной функции - ТС рассматривает файл не как табличный объект БД, а просто как некие бин.данные, при этом ни о каком "построчном" чтении файла речи не идет. Отсюда и высокая скорость сканирования.
> либо ищется вторая запись отделенная пробелами
Судя по приведенному фрагменту содержимого файла, искать ее не надо - смещение и длина 2-го поля(а не записи !) фиксированы.
Отбросив первую строку, получаем данные регулярной структуры, обращение к которым с легкостью осуществляется прямым позиционированием в файле (Seek по расчетному смещению) и чтением с установленной позиции блока байт заранее известного размера (для 2-го поля в приведенном примере - 10 байт)