Потребление памяти при разборе YAML с помощью yaml-cpp

Я разрабатываю приложение Qt для встроенной системы с ограниченной памятью. Мне нужно получить несколько мегабайт данных JSON и проанализировать их как можно быстрее и не используя слишком много памяти.

Я думал об использовании потоков:

Источник JSON (HTTP-клиент) ---> распаковщик ZIP ---> анализатор YAML ----> объекты, сопоставленные с базой данных

Данные будут поступать из сети намного медленнее, чем я смогу их разобрать.

  1. Сколько памяти нужно yaml-cpp для анализа 1 МБ данных?
  2. Я хотел бы, чтобы уже проанализированные необработанные данные из декомпрессора и внутренней памяти, используемые для этих данных парсером YAML, были выпущены, как только будет создан объект, сопоставленный с базой данных. Является ли это возможным?
  3. Поддерживает ли yaml-cpp асинхронный анализ? Поэтому, как только объект JSON проанализирован, я могу сохранить его в базе данных, не дожидаясь полного содержимого из источника HTTP.

person Marcin    schedule 18.05.2014    source источник
comment
Сколько объектов вы получаете? Сколько свойств в каждом объекте? Средний размер каждого свойства? Я yaml-cpp способен парсить по одному объекту по мере их поступления? И вы получаете JSON или YAML?   -  person Some programmer dude    schedule 18.05.2014
comment
Я могу получить несколько тысяч объектов. Это может быть легко 7MB текста. Я использую JSON, который является подмножеством YAML 1.2 и может быть проанализирован с помощью yaml-cpp. Я не знаю, способен ли yaml-cpp анализировать один объект за раз по мере их поступления, так как это часть моего вопроса :)   -  person Marcin    schedule 18.05.2014


Ответы (1)


Поскольку у вас есть ограничения по памяти и ваши данные уже находятся в формате JSON, вам следует использовать парсер JSON с малым объемом памяти вместо парсера YAML. Попробуйте jsoncpp, хотя я не уверен, какова их поддержка потоковой передачи (поскольку в JSON нет концепции документов).

yaml-cpp предназначен для потоковой передачи, поэтому он не будет блокироваться, если есть документы для анализа, но поток все еще открыт; однако существует нерешенная проблема в yaml-cpp. где он читает более одного документа за раз, поэтому он действительно не предназначен для чрезвычайно низкого использования памяти.

Что касается того, сколько памяти требуется для синтаксического анализа 1 МБ данных, то оно, вероятно, составляет порядка 3 МБ (необработанный входной поток, плюс проанализированный поток, плюс результирующая структура данных), но это может сильно различаться в зависимости от типа данных. данных, которые вы анализируете.

person Jesse Beder    schedule 19.05.2014
comment
Можете ли вы предложить некоторые библиотеки C/C++, которые подходят для этой цели? Я быстро поискал в репозитории Ubuntu и не нашел ничего подходящего. Также вы можете ответить на мои 3 вопроса? Из того, что вы говорите, я думаю, что ответ на 2 и 3 - нет. Как насчет первого вопроса? - person Marcin; 20.05.2014
comment
Я вернулся к оптимизации этого куска функционала. Проверил VmPeak своего процесса до разбора и после, оказалось, что VmPeak увеличился на 16МБ. Этот результат был достигнут с помощью gzip-файла JSON размером 84 КБ, что составляет почти 1 МБ после распаковки. По сравнению с этим синтаксический анализ RapidJSON на месте дал мне увеличение на 3 МБ. - person Marcin; 31.10.2016