Почему вы используете для этого семантические действия?Интересная тема для чтения - статья Boost Spirit: «Семантические действия - зло»? и другие заметки.Разбор в структуру AST, как показано в примерах X3, например, Сотрудник - Разбор в структуры ИМО намного более естественен.Для оценки данных вам понадобится шаблон посетителей.
Здесь показано одно решение:
#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/home/x3.hpp>
namespace ast {
struct triple {
double fad;
double fbd;
double value;
};
struct data {
int id;
double target;
std::vector<ast::triple> triple;
};
}
BOOST_FUSION_ADAPT_STRUCT(ast::triple, fad, fbd, value)
BOOST_FUSION_ADAPT_STRUCT(ast::data, id, target, triple)
namespace x3 = boost::spirit::x3;
namespace parser {
using x3::int_; using x3::double_;
auto const triple = x3::rule<struct _, ast::triple>{ "triple" } =
int_ >> ':' >> int_ >> ':' >> double_;
auto const data = x3::rule<struct _, ast::data>{ "data" } =
int_ >> double_ >> +triple;
}
int main()
{
std::stringstream buffer;
std::ifstream file{ R"(C:\data.txt)" };
if(file.is_open()) {
buffer << file.rdbuf();
file.close();
}
auto iter = std::begin(buffer.str());
auto const end = std::cend(buffer.str());
ast::data data;
bool parse_ok = x3::phrase_parse(iter, end, parser::data, x3::space, data);
if(parse_ok && (iter == end)) return true;
return false;
}
Оно компилируется (см. Wandbox ), но не 't протестирован из-за отсутствия входных данных (которые вы можете сгенерировать самостоятельно внутри main()
, конечно), но вы заинтересованы только в сравнительном тестировании.
Также обратите внимание на использование stringstream
для чтения rdbuf
.Есть несколько способов обшарить кошку, я ссылаюсь здесь на Как читать в файле на C ++ , где быстрый подход к чтению rdbuf
.
Далее, как вы провели тест?Просто измерьте время, необходимое для x3::phrase_parse()
соотв.strsep
только часть или двоичная дыра?время загрузки файла включительно?Это должно быть сопоставимо!Также рассмотрим кеширование файловой системы ОС и т. Д.
Кстати, было бы интересно посмотреть результаты и среду тестирования (размер файла данных, strsep
реализация и т. Д.).
Добавление:
Если вы приблизительно знаете, сколько данных вы можете ожидать, вы можете предварительно выделить память для вектора, используя data.triple.reserve(10240);
(или написать собственный конструктор с таким аргументом, как arg).Это предотвращает перераспределение во время синтаксического анализа (не забудьте включить это в блок try / catch для захвата std :: bad_alloc и т. Д.).IIR по умолчанию емкость 1000 на старых GCC.