|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
я согласен с тем что если у нас одна запись может занимать весь файл то данный алгорим не подходит но я об этом и писал уже не раз а исхожу из того что запись гораздо меньше всего файла поэтому то что я ищу назад не критично опять же согласен что это повторная работа но она небольшая на текущий момент я понял что 1 надо читать файл большими кусками 2 бейсик не тормозит 3 анализ текущего буфера можно делать любым алгоритмом 4 когда я знаю максимальный размер записи и она целиком помещается в буфер я использую текущий алгоритм 5 действительно можно просто сначала найти IncomingTime потом UserInfo и все просто это немного другой алгоритм. а я использую тот же алгоритм который был в самом начале в самом первом примере парсинга алгоритм IncomingTime, UserInfo тут проблема в том что мы должны найти UserInfo между IncomingTime а как? если я сначала отсканирую буфер по UserInfo я могу пропустить IncomingTime если я сначала отсканирую буфер по IncomingTime я могу пропустить UserInfo те сканировать надо сразу по двум строкам такой функции нет надо ее писать ... |
|||
:
Нравится:
Не нравится:
|
|||
14.12.2011, 20:26 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
кстати текущая реализация на тестовом примере работает быстро правда размер записи у меня в этом примере небольшой но в любом случае я увеличиваю количество сканирований не больше чем в два раза а время загрузки файла в память гораздо больше времени сканирования этого файла в памяти. сканированием в памяти можно вообще пренебречь. но опять же повторюсь это все работает то тех пор пока запись целиком в буфере ... |
|||
:
Нравится:
Не нравится:
|
|||
14.12.2011, 20:31 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
Может вам это пригодится. Стырено отсюда , там закрыто для незарегистрированных пользователей. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.12.2011, 20:36 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
парсеря согласен с тем что если у нас одна запись может занимать весь файл то данный алгорим не подходит но я об этом и писал уже не раз а исхожу из того что запись гораздо меньше всего файла поэтому то что я ищу назад не критично опять же согласен что это повторная работа но она небольшаяВот в этом и есть твоя главная ошибка. Если Иванов встречается редко - то не критично. Но ты не знаешь насколько редок Иванов. Ты закладываешься на идеальное расположенние данных в потоке и получаешь плохую производительность если данные расположены не идеально. парсералгоритм IncomingTime, UserInfo тут проблема в том что мы должны найти UserInfo между IncomingTime а как? Вот тут: 11753792 я уже показал как это делается. Не смотри на ReadLine если они тебя смущают. Смотри на использование вспомогательной переменной. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.12.2011, 20:54 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
парсеря понимаю задачу так 1 есть несколько файлов логов 2 есть несколько человек о которых надо извлечь информацию из всех логов если это так то ОДИН ЧЕЛОВЕК ЗА ОДИН РАЗ. ПО ГРУППЕ ЛИЦ ИНФОРМАЦИЮ НЕ ИЩЕМ. И фрагмент содержащий UserInfo действительно меньше размера файла. Как правило МНОГО меньше соотношение примерно как десятки МБ (файл) к десяткам Кб(ФРАГМЕНТ). А вообще я вот в какой пограничной ситуации встрял в тупик. Обработать ситуацию когда сам фрагмент лога попадает на границу текста считанного в буфер. Причем если он попадает на границу вконце Фрагмента ФАЙЛА в буфере поймать можно и не сложно, то вот когда НАЧАЛО фрагмента лога в обном фрагменте буфера (ФРАГМЕНТ А) а все остальное во втором фрагменте (ФРАГМЕНТ Б) вызвало небольшие затруднения Фрагмент А Фрагмент Б Код: plaintext 1.
Новый вариант парсера сейчас посмотрю. Особенно мне интеренсно то что вы широко API используете. Есть где поучится и кое что в копилку знаний положить. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.12.2011, 21:06 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
White OwlНикаких "если". Редкость Иванова никак не влияет на задачу. Упрощай: Что изначально нужно? Нужно разбить весь лог на куски. Начало одного куска и начало следующего обозначен строкой в которой есть подстрока ">IncomingTime". Если в куске есть подстрока "Иванов", то этот кусок надо запомнить, иначе проигнорировать. Итого один цикл и в нем два instr или три если текст "Иванов" может появится не только в UserInfo: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
Все, и не надо заниматься многочисленным сканированием во всех направлениях. Принцип KISS никто не отменял. Выглядит на удивление просто. Завтра с утра опробую непременно. А что за принцип KISS??? ... |
|||
:
Нравится:
Не нравится:
|
|||
14.12.2011, 21:13 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
авторWhite Owl 11753792 я только примерно понял что там написано еще раз вопрос IncomingTime IncomingTime UserInfo как нам понять что надо взять втрое IncomingTime тк оно ближе к UserInfo? в примере мы читаем построчно но это значит что конец строки уже кто-то за нас нашел те уже отсканировал этот кусок строки до символа конца строки а мы сканируем уже повторно получили два сканирования ничем не лучше ... |
|||
:
Нравится:
Не нравится:
|
|||
14.12.2011, 21:28 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
авторAlex_men пример не так просто запустить придется сначала его полностью посмотреть в общих чертах чтобы хотя бы параметры передать и понять имя функции запуска спрашивайте если что алгоритм такой размер записи Х размер буфера 2Х тогда если в результате сканирования мы нашли UserInfo во второй половине буфера те позиция >Х and <2х тогда заведомо начало записи лежит в буфере и мы его находим если нашли и конец записи в буфере продолжаем как обычно если не нашли конец записи в буфере то сдвигаем все данные в буфере так чтобы начало записи лежало в позиции 0 ноль и подгружаем новый кусок и ищем конец записи а он заведемо должен быть тк запись загружена с позиции 0 ... |
|||
:
Нравится:
Не нравится:
|
|||
14.12.2011, 21:37 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
авторAlex_men 1 файлов логов один или несколько в которых храниться информация о конкретном человеке? 2 получается что есть кнопка на форме в которой выбираем человека и для этого человека извлекаем инфу но тогда если в следующий раз мы введем другого человека то опять будем все сканировать 3 так вот если в одном файле хранится информация о всех возможных человеках и список этих возможных человеков известен заранее то можно за один проход извлечь всю информацию сохранить и просто показывать при следующем запросе. конечно если логи меняются со временем и нужны самые свежие данные то это не пройдет ... |
|||
:
Нравится:
Не нравится:
|
|||
14.12.2011, 21:49 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
парсер11753792 я только примерно понял что там написаноНуууу.... читай еще раз. Там кода совсем не много. парсереще раз вопрос IncomingTime IncomingTime UserInfo как нам понять что надо взять втрое IncomingTime тк оно ближе к UserInfo?А мне это не нужно, я набиваю буфер строками от одного IncomingTime, до другого IncomingTime. Если во время чтения нашел нужный UserInfo то хорошо, не нашел - тоже хорошо. В буфере не бывает двух IncomingTime, поэтому вопрос "который из них ближе" не имеет смысла. парсерв примере мы читаем построчно но это значит что конец строки уже кто-то за нас нашел те уже отсканировал этот кусок строки до символа конца строки а мы сканируем уже повторно получили два сканирования ничем не лучше В принципе - да. Загрузить весь файл в память и работать с ним как с один длинным текстом в теории будет быстрее чем если читать файл построчно. Но только до определенного предела - чем больше файл, тем больше нужда в свопе. Поэтому на маленьких файлах (до четверти ОЗУ) действительно эффективнее грузить все в память разом и потом разбирать. Потом, примерно до размера в две трети ОЗУ, эффективность обоих методов почти одинакова. А когда файл выходит за размеры физического ОЗУ то грузить весь файл в память категорически противопоказано - будут свопы. И еще не забывай о фоновых задачах - они тоже требуют памяти... А буферизация вообще-то делается всегда. Операция чтения файла всегда делает буферизацию внутри собственных кэшей, которые рассчитываются на основе возможностей железа. Сразу скажу что в Бейсике у тебя нету доступа до этих буферов. Ты тут недавно занимался угадайкой с размером собственных буферов ( 11755841 ), вот эти найденые числа как раз и зависят от тех самых внутренних буферов. Считаешь отношение размер_твоего_буфера / размер_внутреннего_буфера_команды_чтения, чем ближе это отношение к целому числу тем общая скорость работы выше. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.12.2011, 01:07 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
авторА мне это не нужно, я набиваю буфер строками от одного IncomingTime, до другого IncomingTime. Если во время чтения нашел нужный UserInfo то хорошо, не нашел - тоже хорошо. В буфере не бывает двух IncomingTime вот теперь понятно только тогда мне это не очень нравиться тк получается если нашли запись без UserInfo то получается зря делали работу по набиванию буфера я думаю для этого алгоритма быстрее будет прочитать в буфер кусок файла просканировать буфер не набивать результирующий буфер а просто запомнить позицию в сканируемом буфере где нашли IncomingTime а сканирование будет быстрее если двигать позицию всегда на 1 байт вперед и смотреть не находится ли в текущей позиции либо IncomingTime либо UserInfo так получится что мы делаем одно сканирование но сравниваем с двумя строками если мы хотим еще и начало строки поймать то придется и ее добавить те будет три строки для сравнения вот только это все надо написать и измерить время выполнения вариант с использованием именно getline FileSystemObject я вообще не рассматриваю тк он очень медленно читает файл читать надо другой функцией почему-то цикл getline FileSystemObject читал со скоростью 4МБайт/с и быстрее читать не хотел ... |
|||
:
Нравится:
Не нравится:
|
|||
15.12.2011, 02:06 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
парсералгоритм такой размер записи Х размер буфера 2Х тогда если в результате сканирования мы нашли UserInfo во второй половине буфера те позиция >Х and <2х тогда заведомо начало записи лежит в буфере и мы его находим если нашли и конец записи в буфере продолжаем как обычно если не нашли конец записи в буфере то сдвигаем все данные в буфере так чтобы начало записи лежало в позиции 0 ноль и подгружаем новый кусок и ищем конец записи а он заведемо должен быть тк запись загружена с позиции 0 Размер искомого фрагмента лога от IncomingTime до OutgoingTime не фиксирован. Он может быть разным. Поэтому возможен вариант когда прочитали первый фрагмент файла от 0 до 2x и не нашли там UserInfo. Прочитали второй фрагмент нашли там UserInfoа вот IncomingTime от этого UserInfo остался в первой части. Тогда нужно либо переменную strFound постоянно держать в памяти (если действовать как White Owl накоплением) либо я так думаю делать так держать размер буфера побольше, чтобу там умещаляся десяток фрагментов. Тогда при первом сканировании если мы не нашли UserInfo откатываться к ближайшему OutgoingTime. В этом случае следующий фрагмент файла будет начинаться целым, еще не отсканированным фрагментом лога от IncomingTime до OutgoingTime. парсер1 файлов логов один или несколько в которых храниться информация о конкретном человеке? 2 получается что есть кнопка на форме в которой выбираем человека и для этого человека извлекаем инфу но тогда если в следующий раз мы введем другого человека то опять будем все сканировать 3 так вот если в одном файле хранится информация о всех возможных человеках и список этих возможных человеков известен заранее то можно за один проход извлечь всю информацию сохранить и просто показывать при следующем запросе. конечно если логи меняются со временем и нужны самые свежие данные то это не пройдет 1)Файлов логов много. Каждый день формируется свой файл лога, а информацию меньше чем за полгода не запрашивают. Итого за раз обрабатывается 180 файлов и больше, до 5 лет значится 1800-1900 файлов. Поэтому меня быстродействие та и волнует. Сейчас проверю насчет скорости обработки при росте файла (то что написал White Owl ) если действительно на больших файлах скорости окажутся сопоставимы сделаю обработку до 100 Мб через буфер остальное чтением. Но тут дело такое секундомер нужен :) 2 и 3 ) В файле за один день информации по Иванову может и не быть. Например он в отпуске с 5 по 15 был. я этого не знаю зато там есть Сидоров, Петров и Дятлов, так что размер файла все равно большой. Количество таких Ивановый порядка 1000 в системе и это как говорится не предел. Так что парсить ежедневно и раскладывать информацию отдельно по каждому дело абсолютно лишнее, да и место это опять же скушает даже будучи хорошенько заархивировано. плюс каждый день новый лог добавляется, так что по запросу все равно надо делать дополнительную обработку, а нет ли там Иванова. В общем бюджет сделан секндомер на столе пошел разбирать логи. Кстати я так по опытам понял что чем больше фрагмент в буфере тем: 1) выше скорость сканирования 2) Меньше возможностей возникновения пограничных ситуаций и проще их обходить. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.12.2011, 08:58 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
авторРазмер искомого фрагмента лога от IncomingTime до OutgoingTime не фиксирован. Он может быть разным. надо просто чтобы он не превышал какой-то определенной величины если будет в файле запись больше этой величины то прога либо выдаст ошибку либо молча пропустит этот кусок в зависимости от входного параметра авторПоэтому возможен вариант когда прочитали первый фрагмент файла от 0 до 2x и не нашли там UserInfo возможен но я сдвигаю часть буфера от [Х, 2Х] в позицию [0, Х] и подгружаю новый кусок а позицию [Х, 2Х] и теперь он найдется если он там был у меня максимальная скорость чтения (только чтения) файла с диска достигалась при буфере 200МБайт авторФайлов логов много. Каждый день формируется свой файл лога, а информацию меньше чем за полгода не запрашивают. Итого за раз обрабатывается 180 файлов и больше, до 5 лет значится 1800-1900 файлов значит надо сделать то что я предложил в п1 автор1 передавать список файлов логов в функцию парсера и когда полностью прочитаем файл то не выходить из цикла а просто открыть и прочитать следующий файл понятно что формат логов должен быть один и тот же. это позволит не возиться с написанием батников которые по очереди запускают парсинг передавая каждый раз новое имя файла для парсинга кроме того это позволит программно написать создание списка файлов для обработки раз файлов так много значит есть критерий по которому они выбираются для конкретного запроса ... |
|||
:
Нравится:
Не нравится:
|
|||
15.12.2011, 12:19 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
парсер, Критерий очень простой формат имени файла ddmmyyyy.log. У меня кстати на машине P4 2.6 1Гб. Буфер больше 80 метров не уживается пишет OUT OF MEMORY. Далее при поточной обработке файлов через несколько итераций получаю BED FILE NAME OR NUMBER при записи в файл результата Код: vbnet 1.
. я уже и явно номера задал не пойму что делать, не будешь же каждый раз открывать файл перед записью и закрывать после записи. может я что не так делаю. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.12.2011, 12:47 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
Alex_men, Обошел ошибку открывая файл для записи через FSO. Итого по первым тестам 200Мб файл разбор 6 сек. набор файлов в 1ГБ минута. Файлы от 400 кб до 185 мб. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.12.2011, 13:17 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
200Мб файл разбор 6 с это быстро ... |
|||
:
Нравится:
Не нравится:
|
|||
15.12.2011, 13:59 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
> Автор: парсер > 200Мб файл разбор 6 с это быстро Это вопрос или утверждение? Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
15.12.2011, 14:22 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
Игорь Горбонос, Мне тоже интересно. уменьшени с 8 минут до6 секунд это быстро по моим ощущениям. Это отчет в течении часа на любой машине в офисе,а не полутора двух суток на очень хорошей рабочей станции. Пойду теперь смотреть , то что ребята предлагали. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.12.2011, 15:22 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
Вместо того, чтобы каждый раз лопатить одни и те же файлы для разных фамилий, не рациональнее ли пройтись один раз по каждому файлу и создать индексную таблицу1 о смещениях для каждой фамилии. Поля таблицы1: FileName – DataDate – UserName - StartOffset – EndOffset где StartOffset – смещение от начала файла до стартового тэга (начало записи), а EndOffset – смещение от начала файла до завершающего тэга (конец записи) Если файлы данных могут модифицироваться, то хранить отдельную таблицу2 с именами файлов и их DateTimeStamp - ми. В случае, когда дата-время сохранения файла не совпадет с DateTimeStamp, то проиндексировать файл снова и обновить таблицу2.. Поля таблицы2: FileName - DataTimeStamp Тогда любой отчет будет заключаться в открытии файла данных, копировании в буфер фрагмента от начала до конца записи в соответствии с индексной таблицей1 и обработке буфера. Если таблицу сохранить в базе данных, то перед обработкой сначала с помощью SQL-запроса отфильтровать фамилию(и), а затем считать все записи по offset-ам из индексной таблицы и отпарсить. Если длина записи больше, чем позволяет "железо", то воспользоваться советом Antonariy Класс для работы с файлом, проецируемым в память . При этом операционка сама будет оптимально лопатить файл хоть в 2ГБ, с буферизацией, подстроенной под конкретное железо и открытые процессы. Про проецируемые в память файлы хорошо описано у Джеффри Рихтера . Насколько я понял, для автора класса это и было первоисточником. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.12.2011, 18:04 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
самое геморойное это выверять результаты :( ... |
|||
:
Нравится:
Не нравится:
|
|||
15.12.2011, 18:11 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
ZVI, я конечно не много еще знаю но по моему ваш совет а) по временным затратам сопоставим :) Возможно зная смещения информацию из файла можно отобрать быстрее. Но тут еще добавит свою капельку и работа запросов помимо того что все равно надо читать файл и осуществлять позиционирование по нему. А в случае больших файлов и чтение по частям. Не вижу преимуществ, разве что использование проекции в память что то даст. По моему тут как раз тот самый KISS о котором говорилось выше. б) требует постоянной обработки новых файлов чтобы держать базу со смещениями в актуальном состоянии. Или же перед составлением отчета надо пройтись по всем файлам которые не были обработаны со времени предидущего отчета. Дополнить табличку смещений и потом делать отчет. Проекция в память у меня стоит в завтрашнем плане изучения. Это интересная тема. Упоминания я находил в темах но конкретных примеров не было, а за источник информации отдельное СПАСИБО. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.12.2011, 18:28 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
а) Поиск в большом файле с самого начала или считывание фрагмента сразу с нужного offset-а - это 2 большие разницы по времени. А считывание одного и того же большого файла каждый очередной раз, это уже многократное увеличение времени обработки. б) Да, достаточно пройтись только по необработанным файлам, при необходимости можно вообще зарядить обработку на ночь, если работа позволяет. Проецируемые в память файлы в даном случае потребуются только, если размер одной записи слишком большой ... |
|||
:
Нравится:
Не нравится:
|
|||
15.12.2011, 18:49 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
ZVIкаждый очередной раз Имелось в виду для отчете по очередной фамилии. А с индексной таблицей будет достаточного одного прохода по каждой записи. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.12.2011, 18:52 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
парсер, Черт подери эту поддержку вместе с разработчиками. Вы были правы у них таки есть ситуации при которых идет переплетенние двух блоков информации по двум разным клиентам. Причем программа разбора логов разработчиков эти фрагменты вообще игнорит. Есть возможность еще отбирать фрагмет по sessionID но это усложнит все по самое немогу. Прийдется видимо ускорить изучение вопроса проекции файлов ... |
|||
:
Нравится:
Не нравится:
|
|||
16.12.2011, 13:05 |
|
Работа с большими текстовыми файлами.
|
|||
---|---|---|---|
#18+
автору них таки есть ситуации при которых идет переплетенние двух блоков информации по двум разным клиентам не очень понял что это значит но если можно определить это перекрытие тогда может можно и извлечь из этого перекрытия только то что нужно как правило если мы можем извлечь информацию вручную или глазами то и прогу реализующую излечение тоже можно написать все-таки это лог файл а не изображение например авторПрийдется видимо ускорить изучение вопроса проекции файлов не понимаю как это может помочь я думаю вообще проекция файла в память для нашего случая не нужна вот случаи которые приходят в голову когда она действительно может пригодиться 1 загрузка исполняемого файла помимо загрузки кода загрузчик должен настроить таблицу импорта функций а это связано с записью в exe файл тк писать в exe файл нельзя то без проекции в файл пришлось бы выделить буфер записать туда таблицу импорта объяснить системе что таблица импорта теперь находится по новому адресу имея проекцию в файл система автоматически при записи в память выделит место в своп-файле и запишет туда данные при этом адрес данных в памяти вообще не измениться те ключевым здесь является постоянство адреса в памяти 2 мы хотим выделить память которая будет доступна сразу нескольким процессам ... |
|||
:
Нравится:
Не нравится:
|
|||
16.12.2011, 14:53 |
|
|
start [/forum/topic.php?fid=60&msg=37577308&tid=2158182]: |
0ms |
get settings: |
8ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
38ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
56ms |
get tp. blocked users: |
1ms |
others: | 354ms |
total: | 494ms |
0 / 0 |