
Okay, I made a Spirit version and I am wanting to compare times, however no one has posted any compilable code here yet, nor test cases, nor anything I can use, so I am just guessing that it is correct since I have no data to run through it. Since none of the above code actually compiles as-is, and I do not feel like dealing with incomplete examples, here are the times on my computer using the code below. When parsing "42", this would be an example of the fastest case: char const *s1 = "42", *e1 = s1 + std::strlen(s1); boost::long_long_type result; size_t counter = 1000000; while(counter--) parse_price_spirit(s1, e1, result); This executed in no real measurable time... might have been optimized out, let me check the assembly, nope, very much not optimized out, the loop is run, the function is not inlined, and it is indeed called 1000000 times. Okay, running this with 10000000 (7 zero's, 10 million loops, 9 million extra then the above tests) instead takes about ~1.5 seconds. Now running the test with "42.5", which should be the *slowest* possible case for the code I wrote, with 1000000 (6 zero's, one million) it took still no noticeable time. With 10000000 (7 zero's, 10 million) iterations it took roughly about ~1.5 seconds again. I would really love to have the same test cases and scaffolds that everyone else is using so I can do some real timings though. And yes, my parser, for a string it returns -> value: "42" -> 6720000 (42*160000) "42 1/2" -> 6800000 (42*16000 + (1*16000)/2) "42.5" -> 6800000 (42*16000 + floor(160000.0*0.5 + 0.5)) "4.2e1" -> 6720000 (42*160000) This is comparing with someone elses above timings, have no clue of his compile type, hardware, anything, and he did not post his code, but these are the times that he posted:
1) The original code 2) Static const regexes 3) Static const regexes with reused match results objects
I ran each config for 1000000 iterations and got roughly these numbers:
1) ~950 sec 2) ~45 sec 3) ~9 sec
All of the above I did was using MSVC 2k5 in release mode in Windows XP on an old AMD Athlon 1.8ghz Opteron processor. If anyone can give me the above code (his original version and the xpressive version) as compilable files so I do not need to deal with anything, then I can run a proper, full, and millisecond detailed timings. Based on my above timings, either my ancient 1.8ghz computer is rather massively faster then his computer, or Spirit2.1 is much faster then both xpressive and the original code (which someone else said above, the optimized xpressive takes about 20% or so longer I think?). The code, I whipped it up quickly, not pretty, just getting it functional since the guidelines are not very well set, do note, this is not how I normally make my Spirit parsers, but if someone gives me the source of the other things, then I will do this one properly once I confirm that this parses what needs to be parsed (to compile this, make sure you are running Boost Trunk!): #include <boost/tr1/cmath.hpp> #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> BOOST_STATIC_ASSERT(sizeof(boost::long_long_type) == 8); boost::long_long_type tmpResult; inline void dotNumber(const double a1) { tmpResult += static_cast<boost::long_long_type>(std::floor(160000.0*a1 + 0.5)); } template <typename Iterator> bool parse_price_spirit(Iterator first, Iterator last, boost::long_long_type &c) { using boost::spirit::qi::double_; using boost::spirit::qi::_1; using boost::spirit::qi::_2; using boost::spirit::qi::phrase_parse; using boost::spirit::qi::lexeme; using boost::spirit::qi::lit; using boost::spirit::ascii::space; using boost::spirit::ascii::blank; using boost::phoenix::ref; using boost::spirit::long_long; using boost::long_long_type; bool r = phrase_parse(first, last, // Begin grammar // I did not put this in a grammar class because I am being // lazy, plenty of examples of that anyway, and no, it is not // faster here, it is the same speed whether inline here or in // a grammar class. ( (long_long[ref(tmpResult)=(_1*160000)] >> !lit('.') >> -(long_long >> '/' >> long_long)[ref(tmpResult)+=160000*_1/_2]) | double_[&dotNumber] ) // End grammar ,blank); if (!r || first != last) // fail if we did not get a full match return false; c = tmpResult; return r; }