다음 스 니펫이 있습니다.boost :: spirit :: qi perfomance
#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);
}
결과는 빠르게 고전에 비해 너무
[email protected]:~/My_pro1/cpp_pro$ ./simple_j
Size: 3072000
Qi
0
Classic
1
, 제나라 구문 분석이다. 내가 성병 string_ 규칙의 속성 : 문자열() (즉, qi::rule<Iter, std::string()> string_;
)을 변경할 때 내가
[email protected]:~/My_pro1/cpp_pro$ ./simple_j
Size: 3072000
Qi
19
Classic
1
이 매우 - 매우 느리다. 내가 뭔가 잘못하고 있는거야? 감사.
컴파일러 : gcc 4.6.3. 부스트 - 1.48.0. flags : -std = C++ 0x -O2. LWS 결과는 동일합니다. char_ 즉
string_ = qi::char_('"') >> *(qi::char_[boost::bind(&some_f, _1)] - '"')
>> qi::char_('"')[boost::bind(&some_clear_f, _1)];
에 대한 의미 조치
사용은 perfomance을 향상하지만, 만약 존재한다면 내가 너무 다른 해결책을 찾고 있어요.
어떤 컴파일러입니까? 어떤 컴파일러 플래그 (최적화 등)? –
@IgorR. gcc 4.6.3. -std = C++ 0x and -O2 – ForEveR
질문과 비슷한 것 같습니다 : http://stackoverflow.com/questions/13343874/boost-spirit-qi-slow –