Медленная генерация данных C ++ XML и base64 - PullRequest
1 голос
/ 05 марта 2020

В приложении C ++ мне нужно сгенерировать данные base64 и поместить их в XML. Данные поступают из сторонней библиотеки через функцию stati c (int writeData(uint8_t* data, int data_size)).

Код выполняется на Raspberry Pi (ARM1176).

Иногда эта сторонняя библиотека вызывает writeData часто, каждые 5-6 мс. (и это на самом деле не учитывает задержки)

Я создаю XML с Rapid XML, что:

попытка создать самую быструю XML возможен синтаксический анализатор

А для генерации Base64 я использую Boost .

Поскольку первая часть самого XML является stati c Я написал эти части только один раз при инициализации:

xml_document<> XMLDocument;
xml_node<>* XMLNode; //its value will be changed in writeData fn
xml_attribute<>* XMLAttr; //its value will be changed in writeData fn
string XMLOutput; //final xml string
string Base64Data; //base64 data holder

void initXML() {
  // create declaration
  xml_node<>* decl = XMLDocument.allocate_node(node_declaration);
  decl->append_attribute(XMLDocument.allocate_attribute("version", "1.0"));
  decl->append_attribute(XMLDocument.allocate_attribute("encoding", "utf-8"));
  XMLDocument.append_node(decl);

  // create variable attribute
  XMLAttr = XMLDocument.allocate_attribute("id", 0);

  // create variable node
  XMLNode = XMLDocument.allocate_node(node_element, "main");
  XMLNode->append_attribute(XMLAttr);
  XMLNode->value(data.c_str());

  XMLDocument.append_node(XMLNode);
}

Так что в writeData мне нужно будет только сгенерировать base64 и поместить его в эту XML структуру - как можно быстрее.

XMLOutput будет содержать окончательную строку в формате XML.

using namespace boost::archive::iterators;
using It = base64_from_binary<transform_width<uint8_t*, 6, 8>>;

int writeData(uint8_t* data, int data_size) {
  XMLOutput.clear();
  Base64Data = std::string(It(data), It(data + data_size)).append((3 - data_size % 3) % 3, '=');
  XMLAttr->value("newValue");
  XMLNode->value(Base64Data.c_str());
  print(back_inserter(XMLOutput), XMLDocument, print_no_indenting);

  return data_size;
}

Проблема заключается в том, что текущая реализация writeData занимает слишком много времени и вызывает высокую загрузку ЦП.

При пустом writeData он выполняется около 200 раз в секунду. Однако в этой реализации она выполняется только около 40 раз в секунду.

Как можно ускорить генерацию base64 и xml? (Base64 был необходим, потому что XML не разрешает двоичные данные внутри. Я не хочу придерживаться base64, если существует разумный и более быстрый метод).

C ++ Я использую стандарт ISO C ++ 11 (-std = c ++ 0x), оптимизация компилятора выключена (-O0), отладка max (-g3).

1 Ответ

1 голос
/ 05 марта 2020

Я вижу три небольших улучшения эффективности:

  • reserve достаточно места в вашей целевой строке впереди строки Base64, включая отступы;
  • reserve достаточно места в вашем XMLOutput для последней XML строки;
  • Используйте XMLNode->value(Base64Data.c_str(), Base64Data.size()), чтобы избежать дополнительного strlen вызова.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...