Нашли или выдавили из себя код, который нельзя назвать нормальным,
на который без улыбки не взглянешь?
Не торопитесь его удалять или рефакторить, — запостите его на
говнокод.ру, посмеёмся вместе!
Есть штуки три-четыре, на разные вкусы, но тут люди героически решили сделать что-то абсолютно запредельно ненужное.
Обычный парсер генератор создаст какой-нибудь LL(1), или, если нельзя, то LR(1), или можно попробовать PEG (packman parser) - все с хорошо известной асимптотикой и т.д.
Но тут дело в том, что захотелось парсить не все сразу, а с остановками, на манер как SAX может парсить XML. И в этом есть определенный смысл, начиная примерно с мультимегабайтных файлов.
Но в пределах этой библиотеки бультимегабайтные файлы не ожидаются, т.как парсится HTTP ответ от базы данных. Если он будет таких запредельных размеров, то пользоваться этим будет не возможно, даже если памяти на это много и не потребуется. Пользователь на другом конце не станет ждать часами ответа.
> Но тут дело в том, что захотелось парсить не все сразу, а с остановками
ок. тогда без bison/flex. что делает парсинг json из тривиального простым. как раз случай для fsm. и если делать в нативном питоне, то итеративность можно реализовать yield'ами. (я корутинами не пользовался, я такое только через коллбэки реализовывал.)
Да, а как я это обнаружил. Написал запрос. Когда запрос небольшой, то все работает, чуть только доходит до ~50К, код валится с непонятной ошибкой "неожиданый символ Е". Естесственно, в теле ответа символов "Е" несколько сотен, а замечательный парсер не сообщает позицию, где случилась ошибка.
Естесственно, я в первую очередь себя проверял, искал может я что-то не так записал изначально, может быть "Е" - это на самом деле какой-то другой символ, который так странно отобразился и т.д.
Вообще так испахабить идею... это я как бы пытаюсь научиться работать с графовыми базами данных. И, ну просто диву даешся какие идиотские идеи люди приделывают к, вобщем, замечательному основанию. Посмотреть на тот же Сайфер / Гремлина - это ж просто пиздец. Язык который умеет так мало, и при это в нем столько сущностей... Безумная какая-то грамматика, к которой документ был написан каким-то филателистом любителем.
И нормального интерфейса к базе данных нет, т.как сама база написана на Яве, и создатели, естесственно, постарались энтерпрайз налепить. Как встроенную, ее еще можно использовать - но это значит, писать на Яве, т.как ее больше никуда не встроишь. А использовать ее из чего-то другого - пайплайн становится таким невероятно тормозным, что херит на корню все плюшки вобщем-то принципиально очень быстрой бд.
У стандатронго есть колбеки, которые можно было использовать в строительстве, если так сильно хотелось. Это говно как бы ни парсило, все равно будет очень медленным. Лучше уже распарсить весь сишным, но быстро, чем ждать это, но по часттм.
Тут еще такой момент, что все эти ухищрения с постепенным парсингом обламываются об то, что структура иерархическая: ну и что что я смогу распаристь часть, и мне тут же понадобиться узнать сколько дочерних элементов есть у элемента на вершушке иерархии? Если бы это было чем-то вроде таблицы - еще можно понять, а так - бессмысленное извращение.
Сильно зависит от задачи. В большинстве случаев весь контекст знать не нужно. Если мы просто преобразуем список небольших объектов в другой формат, то нам редко нужно знать весь контекст.
Появилось свойство на входе - преобразовали и записали в выход. Если нужно что-то аккумулировать, аккумуляторы выводим последними.
Это даёт возможность обрабатывать большие массивы данных небольшими ресурсами и относительно простым кодом.
К примеру, есть xml-ки в 10Гб и json-файлы аналогичного размера, которые надо конвертировать / заливать в базу. На таких масштабах наивные подходы не работают.
В любом случае, имея pull-парсер, легко построить push-парсер и вообще реализовать любое удобное апи.
Проблема в том, что dom-представление xml-файла, полученное из libxml2, занимает места в несколько раз больше, чем сам файл. Пробовали распарсить в dom - отожрало на сервере 90Gb оперативки 🙂
у нас на проекте нечто подобное. но только с sax, потому что все равно контент перед заливом в базу надо дополнительно обработать.
я конечно повторяюсь, но если у вас 10Гб файлы, но выбор xml как формата файла был очевидно ошибочным. с json я догадываюсь те же яйца. форматы для структурированых данных очень плохо подходят для представления структурированного потока данных.
Этра херня никогда не справится с задачами типа "залить в базу гигабайты данных". Оно работает через HTTP, и накладных расходов на посылку там очень много. 5млн записей за 3 часа: http://stackoverflow.com/questions/19014822 за это же время можно было написать на Яве импорт, начать импорт собственно и закончить.
Но мы говорим про парсер, т.е. про чтение а не про запись. В каком случае нам не нужно будет прочитать весь ответ от сервера? Зачем мы тогда этот запрос посылали вообще? Кроме того, по занимаемой памяти - вовсе не факт, что строка будет занимать меньше памяти, чем собраный объект (числа представленные строкой занимают больше памяти, ключи многих объектов будут почти наверняка повторяться).
Тут было уже упомянута разница между пуш / пул парсерами. Ну вот предположим мы действительно получили очень большой ответ и хотим его переправить по частям дальше по инстанции: опять же, нам ничто не поможет выбросить уже посланные объекты до того, как мы не прочитаем весь объект на верхушке иерархии. Т.е. ради мнимого удобства (а на самом деле просто очевидно потому, что очень хотелось сделать самому) получили и потерю производительности, и баги, и кучу других проблем.
> В каком случае нам не нужно будет прочитать весь ответ от сервера?
XML'ки бывают не только в ответах от сервера. Например стартовая выгрузка того же ФИАС'а (реинкарнация КЛАДР'а) содержит 8 гиговую XML'ку.
Кэп, это библиотека специально написана для того, чтобы парсить ответы от ниофорджа, это часть питунео (они вместо того, чтобы вынести ее во внешние зависимости, встроили ее целиком в свой пакет). У нее даже в теории не предполагается других вариантов использования.
а AST не строится? по дереву разбора можно было бы вернуться, и передавать относительные оффсеты на продвижение парсера по входному файлу, так при падении, вернувшись в корень AST, можно узнать оффсет в во входном файле. Знаю, что деревянный способ - но дереву-деревово, а что тут еще сделать - ХЗ
Ох, блять, это еще не все, как оказалось. Все из того же замечательного файла
Обычный парсер генератор создаст какой-нибудь LL(1), или, если нельзя, то LR(1), или можно попробовать PEG (packman parser) - все с хорошо известной асимптотикой и т.д.
Но тут дело в том, что захотелось парсить не все сразу, а с остановками, на манер как SAX может парсить XML. И в этом есть определенный смысл, начиная примерно с мультимегабайтных файлов.
Но в пределах этой библиотеки бультимегабайтные файлы не ожидаются, т.как парсится HTTP ответ от базы данных. Если он будет таких запредельных размеров, то пользоваться этим будет не возможно, даже если памяти на это много и не потребуется. Пользователь на другом конце не станет ждать часами ответа.
ок. тогда без bison/flex. что делает парсинг json из тривиального простым. как раз случай для fsm. и если делать в нативном питоне, то итеративность можно реализовать yield'ами. (я корутинами не пользовался, я такое только через коллбэки реализовывал.)
Естесственно, я в первую очередь себя проверял, искал может я что-то не так записал изначально, может быть "Е" - это на самом деле какой-то другой символ, который так странно отобразился и т.д.
Вообще так испахабить идею... это я как бы пытаюсь научиться работать с графовыми базами данных. И, ну просто диву даешся какие идиотские идеи люди приделывают к, вобщем, замечательному основанию. Посмотреть на тот же Сайфер / Гремлина - это ж просто пиздец. Язык который умеет так мало, и при это в нем столько сущностей... Безумная какая-то грамматика, к которой документ был написан каким-то филателистом любителем.
И нормального интерфейса к базе данных нет, т.как сама база написана на Яве, и создатели, естесственно, постарались энтерпрайз налепить. Как встроенную, ее еще можно использовать - но это значит, писать на Яве, т.как ее больше никуда не встроишь. А использовать ее из чего-то другого - пайплайн становится таким невероятно тормозным, что херит на корню все плюшки вобщем-то принципиально очень быстрой бд.
teh drama
> teh drama
есть такие как мы, которые это говном называют.
а есть продвинутые которые клиентам под это дело консалтинг продают и еще больше энтерпрайза лепят - и бабло большое за это имеют.
А что, есть стандартный потоковый pull-парсер? Вижу json.iterencode, iterdecode не наблюдаю.
Появилось свойство на входе - преобразовали и записали в выход. Если нужно что-то аккумулировать, аккумуляторы выводим последними.
Это даёт возможность обрабатывать большие массивы данных небольшими ресурсами и относительно простым кодом.
К примеру, есть xml-ки в 10Гб и json-файлы аналогичного размера, которые надо конвертировать / заливать в базу. На таких масштабах наивные подходы не работают.
В любом случае, имея pull-парсер, легко построить push-парсер и вообще реализовать любое удобное апи.
Покупаем больше памяти, и 10 гиг в нее входят 😉
Нищебродский сервак. Всего 90 гигов. Само собой этого не хватит...
я конечно повторяюсь, но если у вас 10Гб файлы, но выбор xml как формата файла был очевидно ошибочным. с json я догадываюсь те же яйца. форматы для структурированых данных очень плохо подходят для представления структурированного потока данных.
Ключи повторяются, но вот либа, похоже, не утруждает себя их интернированием. Разбираться не стали, просто переписали.
Но мы говорим про парсер, т.е. про чтение а не про запись. В каком случае нам не нужно будет прочитать весь ответ от сервера? Зачем мы тогда этот запрос посылали вообще? Кроме того, по занимаемой памяти - вовсе не факт, что строка будет занимать меньше памяти, чем собраный объект (числа представленные строкой занимают больше памяти, ключи многих объектов будут почти наверняка повторяться).
Тут было уже упомянута разница между пуш / пул парсерами. Ну вот предположим мы действительно получили очень большой ответ и хотим его переправить по частям дальше по инстанции: опять же, нам ничто не поможет выбросить уже посланные объекты до того, как мы не прочитаем весь объект на верхушке иерархии. Т.е. ради мнимого удобства (а на самом деле просто очевидно потому, что очень хотелось сделать самому) получили и потерю производительности, и баги, и кучу других проблем.
> Задумку авторов того, что в посте, я, разумеется, не одобряю и не оправдываю.
XML'ки бывают не только в ответах от сервера. Например стартовая выгрузка того же ФИАС'а (реинкарнация КЛАДР'а) содержит 8 гиговую XML'ку.
Ваш кэп.
?