Форум программистов, компьютерный форум, киберфорум
Наши страницы
Boost C++
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
ForEveR
В астрале
Эксперт С++
7996 / 4755 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
1

Производительность boost::spirit::qi

18.01.2013, 20:18. Просмотров 1067. Ответов 1
Метки нет (Все метки)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <iostream>
#include <sstream>
#include <chrono>
 
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/classic.hpp>
 
namespace qi = boost::spirit::qi;
namespace classic = boost::spirit::classic;
 
template<typename T>
void output_time(const T& end, const T& begin)
{
   std::cout << std::chrono::duration_cast<std::chrono::seconds>(
         end - begin).count() << std::endl;
}
 
template<typename Iter>
struct qi_grammar : public qi::grammar<Iter>
{
   qi_grammar():qi_grammar::base_type(rule_)
   {
      rule_ = *string_;
      string_ = qi::char_('"') >> *(qi::char_ - '"') >> qi::char_('"');
   }
   qi::rule<Iter> rule_;
   qi::rule<Iter> string_;
};
 
template<typename Iter>
struct classic_grammar : public classic::grammar<classic_grammar<Iter>>
{
   template<typename ScannerT>
   struct definition
   {
      definition(const classic_grammar&)
      {
         rule = *string_;
         string_ = classic::ch_p('"') >> *(classic::anychar_p - '"') >> classic::ch_p('"');
      }
      classic::rule<ScannerT> rule, string_;
      const classic::rule<ScannerT>& start() const { return rule; }
   };
};
 
template<typename Iter>
void parse(Iter first, Iter last, const qi_grammar<Iter>& prs)
{
   auto start = std::chrono::system_clock::now();
   for (int i = 0; i < 100; ++i)
   {
      Iter next = first;
      if (!qi::parse(next, last, prs) || next != last)
      {
         assert(false);
      }
   }
   auto finish = std::chrono::system_clock::now();
   output_time(finish, start);
}
 
template<typename Iter>
void parse_c(Iter first, Iter last, const classic_grammar<Iter>& prs)
{
   auto start = std::chrono::system_clock::now();
   for (int i = 0; i < 100; ++i)
   {
      auto info = classic::parse(first, last, prs);
      if (!info.hit) assert(false);
   }
   auto finish = std::chrono::system_clock::now();
   output_time(finish, start);
}
 
int main()
{
   qi_grammar<std::string::const_iterator> qi_lexeme;
   classic_grammar<std::string::const_iterator> classic_lexeme;
   std::stringstream ss;
   for (int i = 0; i < 1024 * 500; ++i)
   {
      ss << "\"name\"";
   }
   const std::string s = ss.str();
   std::cout << "Size: " << s.size() << std::endl;
   std::cout << "Qi" << std::endl;
   parse(s.begin(), s.end(), qi_lexeme);
   std::cout << "Classic" << std::endl;
   parse_c(s.begin(), s.end(), classic_lexeme);
}
Bash
1
2
3
4
5
6
forever@pterois:~/My_pro1/cpp_pro$ ./simple_j 
Size: 3072000
Qi
0
Classic
1
Если же поменять правило string_ на
C++
1
qi::rule<Iter, std::string()> string_;
получаю

Bash
1
2
3
4
5
6
forever@pterois:~/My_pro1/cpp_pro$ ./simple_j 
Size: 3072000
Qi
19
Classic
1
Это катастрофически медленно. Что можно с этим сделать, используя qi? Или же, это так и должно быть?

Добавлено через 3 часа 57 минут
Один из возможных вариантов - добавить semantic action для сохранения чаров в строку... Ускоряет значительно. Но неужели нет других вариантов?
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.01.2013, 20:18
Ответы с готовыми решениями:

Метапрограммирование в boost::proto (boost::spirit)
В библиотеке boost:: proto есть такой код ...

boost::spirit
Пишу парсер на спирите. Задаюсь вопросом как нормально сделать примерно такое ...

Boost::Spirit. Разбор конфигурационного файла
Есть конфигурационный файл, содержащий текстовое описание данных. Каждая...

Boost начало работы: Undefined reference to `boost::system::generic_category() '
Добрый день Собственно говоря возникла необходимость использовать boost в...

Boost Log - undefined reference to `boost::system::system_category()'
Пытаюсь скомпилировать код из примеров Boost Log:#include...

1
ForEveR
В астрале
Эксперт С++
7996 / 4755 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
20.01.2013, 01:18  [ТС] 2
На стеке дали аж два совета.
Первый - это использовать семантические действия, второй - использовать директиву qi::raw. Читал доку два дня, а qi::raw пропустил... Стыдно даже.
http://stackoverflow.com/questions/1...16222#14416222
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.01.2013, 01:18

Использование boost и boost.build с несколькими компиляторами
Здравствуйте! Собрал библиотеку boost и boost.build для двух компиляторов:...

Spirit::qi - семантическое действие
Суть - парсим значения в мапу (ключ, значение), после, есть правило expr,...

Spirit не видит юникод символы
Здавствуйте форумчане. Необходимо разобрать строку и заполнить полученными...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru