Attribute propagation vs. Semantic actions
Joel de Guzman <[email protected]> Tue, 16 Mar 2010 21:11:44 +0800
| Newsgroups | gmane.comp.parsers.spirit.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi Y'all,
CC'ing Hartmut and John Wilkinson.
I've been looking into attribute propagation vs. semantic actions
lately. It has come to my attention that attribute propagation is
not as efficient as we thought it would be (perhaps due to some recent
changes and strategies we have incorporated). Here's a test case
that does the same thing with attribute propagation and with semantic
actions. Just define ATTR_PROPAGATE to choose the former, or undefine
for the latter. Here's the printout with attribute propagation:
default construct
construct from char
assign
copy construct
default construct
construct from char
assign
copy construct
copy construct
default construct
assign
construct from char
assign
copy construct
copy construct
copy construct
default construct
assign
construct from char
assign
copy construct
copy construct
copy construct
copy construct
default construct
assign
construct from char
assign
copy construct
copy construct
copy construct
copy construct
copy construct
default construct
assign
Now with actions:
construct from char
copy construct
construct from char
copy construct
copy construct
construct from char
copy construct
copy construct
copy construct
construct from char
copy construct
copy construct
copy construct
copy construct
construct from char
copy construct
copy construct
copy construct
copy construct
copy construct
Obviously, the one with semantic actions win. Notice though that
on both cases, there's way too much copying. I suspect unwanted
copying of the vector. Man, this is unacceptable. We have to fix this!
Regards,
--
Joel de Guzman
http://www.boostpro.com
http://spirit.sf.net
http://www.facebook.com/djowel
Meet me at BoostCon
http://www.boostcon.com/home
http://www.facebook.com/boostcon
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Spirit-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-devel
attr_vs_actions.cpp
(text/x-c++src, 2.2 KB)
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
#include <iostream>
#include <string>
#include <complex>
using boost::spirit::qi::grammar;
using boost::spirit::qi::rule;
using boost::spirit::qi::char_;
using boost::spirit::qi::parse;
using boost::spirit::qi::_val;
using boost::spirit::qi::_1;
using boost::phoenix::push_back;
//~ #define ATTR_PROPAGATE
struct test_attr
{
test_attr()
{
std::cout << "default construct" << std::endl;
}
test_attr(char)
{
std::cout << "construct from char" << std::endl;
}
test_attr(test_attr const&)
{
std::cout << "copy construct" << std::endl;
}
test_attr& operator=(test_attr const&)
{
std::cout << "assign" << std::endl;
return *this;
}
};
template <typename Iterator>
struct test_parser : grammar<Iterator, std::vector<test_attr>() >
{
test_parser() : test_parser::base_type(start)
{
#ifdef ATTR_PROPAGATE
start = char_ >> *(',' >> char_);
#else
start = char_[push_back(_val, _1)] >> *(',' >> char_[push_back(_val, _1)]);
#endif
}
rule<Iterator, std::vector<test_attr>()> start;
};
int main()
{
typedef std::string::const_iterator iterator_type;
typedef test_parser<iterator_type> test_parser;
test_parser g;
std::string str = "a,b,c,d,e";
std::vector<test_attr> result;
std::string::const_iterator iter = str.begin();
std::string::const_iterator end = str.end();
bool r = parse(iter, end, g, result);
if (r && iter == end)
{
std::cout << "-------------------------\n";
std::cout << "Parsing succeeded\n";
std::cout << "\n-------------------------\n";
}
else
{
std::cout << "-------------------------\n";
std::cout << "Parsing failed\n";
std::cout << "-------------------------\n";
}
std::cout << "Bye... :-) \n\n";
return 0;
}