<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Boost.Spirit &#187; User Experience</title>
	<atom:link href="http://boost-spirit.com/home/category/user-experience/feed/" rel="self" type="application/rss+xml" />
	<link>http://boost-spirit.com/home</link>
	<description>Home of The Boost.Spirit Library</description>
	<lastBuildDate>Sun, 04 Dec 2011 22:11:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>How to Optimize Qi</title>
		<link>http://boost-spirit.com/home/2011/07/23/how-to-optimize-qi/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-optimize-qi</link>
		<comments>http://boost-spirit.com/home/2011/07/23/how-to-optimize-qi/#comments</comments>
		<pubDate>Sat, 23 Jul 2011 15:49:28 +0000</pubDate>
		<dc:creator>Hartmut Kaiser</dc:creator>
				<category><![CDATA[Qi Example]]></category>
		<category><![CDATA[User Experience]]></category>
		<category><![CDATA[Qi]]></category>

		<guid isPermaLink="false">http://boost-spirit.com/home/2011/07/23/how-to-optimize-qi/</guid>
		<description><![CDATA[Mike Lewis posted a marvelous experience report dubbed ‘Optimizing Boost Spirit &#8211; Blazing fast AST generation using boost::spirit’. He describes how he took an old compiler for the Epoch programming language (which was based on Spirit.Classic) and tuned it for performance using Spirit.Qi and Spirit.Lex. His results are exceptional, he got roughly a thousand fold [...]<br /><div><img src="http://boost-spirit.com/home/wp-content/plugins/gd-star-rating/gfx.php?value=5.0" /></div><div>Rating: 5.0/<strong>5</strong> (4 votes cast)</div><br />]]></description>
			<content:encoded><![CDATA[<p>Mike Lewis posted a marvelous experience report dubbed ‘<a href="http://code.google.com/p/scribblings-by-apoch/wiki/OptimizingBoostSpirit" target="_blank">Optimizing Boost Spirit &#8211; Blazing fast AST generation using boost::spirit</a><em>’.</em> He describes how he took an old compiler for the <a href="http://code.google.com/p/epoch-language/" target="_blank">Epoch</a> programming language (which was based on S<em>pirit.Classic)</em> and tuned it for performance using <em>Spirit.Qi</em> and <em>Spirit.Lex</em>. His results are exceptional, he got roughly a thousand fold speedup compared to the old version. The complete code for his compiler can be downloaded from <a href="http://code.google.com/p/epoch-language/source/browse/" target="_blank">here</a>.</p>
<p><span id="more-1519"></span></p>
<p>He writes:</p>
<blockquote><p>This code illustrates several advanced techniques for parsing large inputs with complex Spirit grammars:</p>
<ul>
<li>Deferred construction and minimal copying of attribute values</li>
<li>Lexical analysis for faster backtracking</li>
<li>A special directive for using qi::symbols alongside a lexer</li>
<li>Linear allocators for faster AST node allocation</li>
<li>Intrusive reference counting for even faster AST node allocation/copying</li>
<li>Grammar transformations for general optimality</li>
<li>Abuse of the &amp;-predicate for skipping expensive productions</li>
<li>Dividing grammars into multiple implementation files for minimal recompilation times</li>
</ul>
</blockquote>
<p>Thanks Mike for sharing your work! I’m sure many <em>Spirit</em> developers will find it very enlightening and encouraging to read about your work. Keep up the excellent work!</p>
<br /><div><img src="http://boost-spirit.com/home/wp-content/plugins/gd-star-rating/gfx.php?value=5.0" /></div><div>Rating: 5.0/<strong>5</strong> (4 votes cast)</div><br />]]></content:encoded>
			<wfw:commentRss>http://boost-spirit.com/home/2011/07/23/how-to-optimize-qi/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Spirit.Qi in the Real World</title>
		<link>http://boost-spirit.com/home/2011/06/08/spirit-qi-in-the-real-world/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=spirit-qi-in-the-real-world</link>
		<comments>http://boost-spirit.com/home/2011/06/08/spirit-qi-in-the-real-world/#comments</comments>
		<pubDate>Wed, 08 Jun 2011 21:34:32 +0000</pubDate>
		<dc:creator>Joel de Guzman</dc:creator>
				<category><![CDATA[Beginner]]></category>
		<category><![CDATA[Boost Con 2011]]></category>
		<category><![CDATA[BoostCon]]></category>
		<category><![CDATA[Experience Level]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Intermediate]]></category>
		<category><![CDATA[Qi Example]]></category>
		<category><![CDATA[User Experience]]></category>
		<category><![CDATA[BoostCon 2011]]></category>

		<guid isPermaLink="false">http://boost-spirit.com/home/?p=1496</guid>
		<description><![CDATA[This is the first time I missed attending BoostCon (May 15-20, 2011 – Aspen, Colorado). Fortunately, for us who were not able to attend, Marshall Clow uploaded some videos. Here&#8217;s one one that&#8217;s relevant to Spirit: &#8220;Spirit.Qi in the Real World&#8221;, by Robert Stewart. Watch the presentation here: http://blip.tv/boostcon/spirit-qi-in-the-real-world-5254335 You can find the slides here: [...]<br /><div><img src="http://boost-spirit.com/home/wp-content/plugins/gd-star-rating/gfx.php?value=5.0" /></div><div>Rating: 5.0/<strong>5</strong> (1 vote cast)</div><br />]]></description>
			<content:encoded><![CDATA[<p>This is the first time I missed attending BoostCon (May 15-20, 2011 – Aspen, Colorado). Fortunately, for us who were not able to attend, Marshall Clow uploaded some videos. Here&#8217;s one one that&#8217;s relevant to Spirit: &#8220;Spirit.Qi in the Real World&#8221;, by Robert Stewart. Watch the presentation here:</p>
<p><a href="http://blip.tv/boostcon/spirit-qi-in-the-real-world-5254335">http://blip.tv/boostcon/spirit-qi-in-the-real-world-5254335</a></p>
<p>You can find the slides here: <a rel="nofollow" href="https://github.com/boostcon/2011_presentations/raw/master/tue/spirit_qi_in_the_real_world.pdf">https://github.com/boostcon/2011_presentations/raw/master/tue/spirit_qi_in_the_real_world.pdf</a></p>
<blockquote><p>Past sessions on Spirit have focused on introducing Spirit or showing  extracts of real use, intermingled with tutorial highlights. Upon  writing real Spirit.Qi parsers, however, one quickly discovers that &#8220;the  devil is in the details.&#8221; There are special cases, tricks, and idioms  that one must discover by trial and error or, perhaps, by following the  Spirit mailing list, all of which take time and may not be convenient.  In this session, we’ll walk through the development of a Spirit.Qi  parser for printf()-style format strings. The result will be a  replacement for printf() that is typesafe and efficient.</p></blockquote>
<br /><div><img src="http://boost-spirit.com/home/wp-content/plugins/gd-star-rating/gfx.php?value=5.0" /></div><div>Rating: 5.0/<strong>5</strong> (1 vote cast)</div><br />]]></content:encoded>
			<wfw:commentRss>http://boost-spirit.com/home/2011/06/08/spirit-qi-in-the-real-world/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Dispatching on Expectation Point Failures</title>
		<link>http://boost-spirit.com/home/2011/02/28/dispatching-on-expectation-point-failures/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=dispatching-on-expectation-point-failures</link>
		<comments>http://boost-spirit.com/home/2011/02/28/dispatching-on-expectation-point-failures/#comments</comments>
		<pubDate>Mon, 28 Feb 2011 14:23:06 +0000</pubDate>
		<dc:creator>Rob Stewart</dc:creator>
				<category><![CDATA[Intermediate]]></category>
		<category><![CDATA[Qi Example]]></category>
		<category><![CDATA[Spirit2 Release]]></category>
		<category><![CDATA[User Experience]]></category>

		<guid isPermaLink="false">http://boost-spirit.com/home/?p=1364</guid>
		<description><![CDATA[When using expectation points, a parsing failure results in an exception that generically indicates the failure, but probably doesn&#8217;t explain the problem in the most meaningful way. It is possible to attach an error handler to react to the failed match in a more specialized way: That will produce a message like the following on [...]<br /><div><img src="http://boost-spirit.com/home/wp-content/plugins/gd-star-rating/gfx.php?value=5.0" /></div><div>Rating: 5.0/<strong>5</strong> (3 votes cast)</div><br />]]></description>
			<content:encoded><![CDATA[<p>When using expectation points, a parsing failure results in an exception that generically indicates the failure, but probably doesn&#8217;t explain the problem in the most meaningful way. It is possible to attach an error handler to react to the failed match in a more specialized way:</p>
<p><span id="more-1364"></span></p>
<pre class="brush: cpp; title: ; notranslate">
rule = alpha &gt; '!';
on_error&lt;fail&gt;(rule,
   std::cerr &lt;&lt; val(&quot;Expected '!' at offset &quot;) &lt;&lt; (_3 - _1)
      &lt;&lt; &quot; in \&quot; &lt;&lt; std::string(_1, _2) &lt;&lt; '&quot;'
      &lt;&lt; std::endl);
</pre>
<p>That will produce a message like the following on stderr:</p>
<p><code> Expected '!' at offset 7 in "Some input"</code></p>
<p>However, if there&#8217;s more than one expectation point in a rule, then the  diagnostic may be unhelpfully generic. To do otherwise, one must distinguish which  expectation point failed. While it is certainly possible to factor the  grammar into additional rules in order to have at most one expectation  point per rule, that&#8217;s not necessary and can make the grammar less readable than otherwise. Instead, the <em>what</em> parameter (<code>_4</code>) of the error handler can be used:</p>
<pre class="brush: cpp; title: ; notranslate">
rule = alpha &gt; '!';
on_error&lt;fail&gt;(rule,
   std::cerr &lt;&lt; val(&quot;Expected &quot; &lt;&lt; _4 &lt;&lt; &quot; at offset &quot;)
      &lt;&lt; (_3 - _1) &lt;&lt; &quot; in \&quot; &lt;&lt; std::string(_1, _2) &lt;&lt; '&quot;'
      &lt;&lt; std::endl);
</pre>
<p>The <em>what</em> parameter describes the failure.  In the case of an expectation point match failure, it is the name of the parser that failed to match or, if the parser is to match literal text, like <code>'!'</code> in the preceding example, the <em>what</em> parameter will be <code>"literal-char"</code> or similar. In this case, <code>_4</code> will be <code>"literal-char"</code> (in the form of a boost::spirit::utf8_string which is a specialization of std::basic_string), and thus not terribly useful in a diagnostic.</p>
<p>To make the error message more helpful, and especially in rules with more than one literal parser to distinguish, create distinct, named rules:</p>
<pre class="brush: cpp; title: ; notranslate">
exclamation = lit('!');
exclamation.name(&quot;!&quot;);
rule = alpha &gt; exclamation;
on_error&lt;fail&gt;(rule,
   std::cerr &lt;&lt; val(&quot;Expected &quot;) &lt;&lt; _4 &lt;&lt; &quot; at offset &quot;
      &lt;&lt; (_3 - _1) &lt;&lt; &quot; in \&quot; &lt;&lt; std::string(_1, _2) &lt;&lt; '&quot;'
      &lt;&lt; std::endl);
</pre>
<p>This will report <code>Expected ! at offset...</code> when the exclamation rule fails to match.</p>
<p>Since an expectation point failure is distinguished by the <em>what</em> parameter, it follows that the <em>what</em> parameter can be used to dispatch to different behavior in the error handler based upon which expectation point failed to match. Doing so can be as simple as passing the <em>what</em> parameter to an error handling function which can use normal C++ techniques for dispatch such as cascading if-else&#8217;s or a map lookup, using the <em>what</em> string as the key to find a function to call. However, Phoenix offers power to do that work within the context of the <code>on_error()</code> call:</p>
<pre class="brush: cpp; title: ; notranslate">
semicolon = lit(';');
semicolon.name(&quot;;&quot;);
rule = alpha &gt; semicolon &gt; alpha;
on_error&lt;fail&gt;(rule,
   let(_a = bind(&amp;boost::spirit::info::tag, _4))
   [
      if_(&quot;;&quot; == _a)
      [
         report_missing(_4, _1, _2, _3)
      ]
      .else_
      [
         if_(&quot;alpha&quot; == _a)
         [
            report_missing(&quot;second word&quot;, _1, _2, _3)
         ]
         .else_
         [
            report_error(_4, _1, _2, _3)
         ]
      ]
   ]);
</pre>
<p>For the last example to compile, a number of include and using directives are necessary beyond the basics you are probably accustomed to seeing:</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;boost/spirit/home/phoenix/bind/bind_member_variable.hpp&gt;
#include &lt;boost/spirit/home/phoenix/scope/let.hpp&gt;
#include &lt;boost/spirit/home/phoenix/scope/local_variable.hpp&gt;
#include &lt;boost/spirit/home/phoenix/statement/if.hpp&gt;
using boost::phoenix::local_names;
</pre>
<p>It would seem, at first blush, that comparing to <code>_4</code> directly should work, but it doesn&#8217;t because <code>_4</code> is a Phoenix actor. Instead, a string type is needed to support the comparisons against the string literals for dispatching. In this example, a local Phoenix variable, <code>_a</code> is declared and assigned the result of binding <code>_4</code> to boost::spirit::info::tag, the field of the boost::spirit::info struct that contains the <em>what</em> string. Thus, <code>_a</code> is a variable local to the error handler that is bound to the boost::spirit::utf8_string that describes the error and supports comparisons. Note the use of Phoenix&#8217;s <code>let</code> construct to declare a local variable scope. (This <code>_a</code>, which is <code>boost::phoenix::local_names::_a</code>, can be ambiguous with <code>boost::spirit::qi::_a</code>, depending upon using directives and declarations.)</p>
<p>The two functions, <code>report_missing()</code> and <code>report_error()</code> are not defined here, but presumably would report on stderr or raise an exception to indicate that a parsing error occurred, and would report the error context from the input range <code>[_1,_2)</code> and would note the error location, within that range, as given by <code>_3</code>.</p>
<p>When dispatching in this manner, there can be other parsing errors besides expectation point match failures, hence the final <code>.else_</code> branch in the example error handler. For lack of a better response, the example just reports a generic error message that includes the <em>what</em> parameter's text to give some sort of explanation. A real world rule would possibly provide a more context-specific diagnostic.</p>
<p>A final caution regarding this technique: the compile time, maintenance burden, and code size increases with each additional expectation point to be handled. Using a map-based dispatch may well be better when the number of expectation points grows. However, the diagnostic text generation may get out of synchronization with the point in the grammar triggering it because of their being located in different parts of the code.</p>
<p>There is another way to keep the diagnostic text near the rule triggering an error, while avoiding a great deal of code within the grammar. It involves collecting the rule name and corresponding diagnostic in a structure stored in an array that is then passed to an error handler that uses the <em>what</em> parameter to select a diagnostic from the array. If that was as clear as mud, don't worry. The code should make it clear. Let's start with the rule name to diagnostic mapping which combines the structure and array within a class template:</p>
<pre class="brush: cpp; title: ; notranslate">
template &lt;size_t N&gt;
class diagnostics
{
public:
   diagnostics();

   // Adds a tag and diagnostic message pair to self.
   void
   add(char const * _tag, char const * _diagnostic);

   // Returns the diagnostic, if any, for _tag.
   char const *
   operator [](char const * _tag) const;

private:
   struct entry
   {
      char const * tag;
      char const * diagnostic;
   };

   entry  entries_[N];
   size_t size_;
};
</pre>
<p>diagnostics, as written, simply saves pointers to string literals. For more flexibility, it could store real strings (std::basic_string&lt;&gt;s, for instance), but this design is useful and simpler for exposition. To use diagnostics, one must create a grammar data member for each rule that will use it, and then populate it as needed by the rule:</p>
<pre class="brush: cpp; title: ; notranslate">
semicolon = lit(';');
semicolon.name(&quot;;&quot;);
rule = alpha &gt; semicolon &gt; alpha;
diags.add(&quot;;&quot;, &quot;Missing semicolon after first word&quot;);
diags.add(&quot;alpha&quot;, &quot;Missing second word&quot;);
on_error&lt;fail&gt;(rule,
   error_handler(ref(diags), _1, _2, _3, _4));
</pre>
<p>Notice how the first expectation point is identified by a named rule for the required semicolon, which will produce an error message or exception containing the diagnostic text <code>"Missing semicolon after first word"</code>. Similarly, if there is no word after a semicolon, then the diagnostic <code>"Missing second word"</code> will be used because the second alpha will fail to match. In each case, the expectation is that the error handler will use <code>_4</code> to indicate which rule fail to satisfy an expectation point.</p>
<p>To round out this example, here's how <code>error_handler()</code> might look:</p>
<pre class="brush: cpp; title: ; notranslate">
struct error_handler_impl
{
   template &lt;class, class, class, class, class&gt;
   struct result { typedef void type; };

   template &lt;class D, class B, class E, class W, class I&gt;
   void
   operator ()(D const &amp; _diagnostics, B _begin, E _end,
      W _where, I const &amp; _info) const
   {
      utf8_string const &amp; tag(_info.tag);
      char const * const what(tag.c_str());
      char const * diagnostic(_diagnostics[what]);
      std::string scratch;
      if (!diagnostic)
      {
         scratch.reserve(25 + tag.length());
         scratch = &quot;Invalid syntax: expected &quot;;
         scratch += tag;
         diagnostic = scratch.c_str();
      }
      raise_parsing_error(diagnostic, _begin, _end,
         _where);
   }
};
phx::function&lt;error_handler_impl&gt; error_handler;
</pre>
<p>You're probably wondering where the implementation of diagnostics' member functions are to be found. Here they are:</p>
<pre class="brush: cpp; title: ; notranslate">
template &lt;size_t N&gt;
inline
diagnostics&lt;N&gt;::diagnostics()
   : size_(0)
{
}

template &lt;size_t N&gt;
void
diagnostics&lt;N&gt;::add(char const * const _tag,
   char const * const _diagnostic)
{
   assert(size_ &lt; N);
   entry &amp; e(entries_[size_++]);
   e.tag = _tag;
   e.diagnostic = _diagnostic;
}

template &lt;size_t N&gt;
char const *
diagnostics&lt;N&gt;::operator [](char const * const _tag) const
{
   for (size_t i(0); i &lt; size_; ++i)
   {
      entry const &amp; e(entries_[i]);
      if (0 == std::strcmp(e.tag, _tag))
      {
         return e.diagnostic;
      }
   }
   return 0;
}
</pre>
<p>It should now be apparent that there are numerous ways to dispatch error handling when using expectation points, but all revolve around decoding the <em>what</em> parameter. In the end, factor your grammar to be functional and readable and then consider which expectation point failure dispatching technique fits best without sacrificing readability or performance.</p>
<br /><div><img src="http://boost-spirit.com/home/wp-content/plugins/gd-star-rating/gfx.php?value=5.0" /></div><div>Rating: 5.0/<strong>5</strong> (3 votes cast)</div><br />]]></content:encoded>
			<wfw:commentRss>http://boost-spirit.com/home/2011/02/28/dispatching-on-expectation-point-failures/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Using Boost.Spirit V2: Qi and Karma</title>
		<link>http://boost-spirit.com/home/2010/12/03/using-boost-spirit-v2-qi-and-karma/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-boost-spirit-v2-qi-and-karma</link>
		<comments>http://boost-spirit.com/home/2010/12/03/using-boost-spirit-v2-qi-and-karma/#comments</comments>
		<pubDate>Sat, 04 Dec 2010 04:04:46 +0000</pubDate>
		<dc:creator>Joel de Guzman</dc:creator>
				<category><![CDATA[Beginner]]></category>
		<category><![CDATA[BoostCon 2010]]></category>
		<category><![CDATA[User Experience]]></category>
		<category><![CDATA[Karma]]></category>
		<category><![CDATA[Qi]]></category>

		<guid isPermaLink="false">http://boost-spirit.com/home/?p=1263</guid>
		<description><![CDATA[These are links to the slides and video of Michael Caisse&#8217;s BoostCon 2010 talk: slides: &#60;http://www.objectmodelingdesigns.com/boostcon10/&#62; video: &#60;http://blip.tv/file/4143337 &#62; Enjoy! Machinery, sensors, equipment, client/server communications, even file formats&#8230; Parsing and producing communication streams is everywhere you look. Often these tasks are simple or small enough to tempt ad-hoc solutions. The Spirit 2.1 library provides a [...]<br /><div><img src="http://boost-spirit.com/home/wp-content/plugins/gd-star-rating/gfx.php?value=3.5" /></div><div>Rating: 3.5/<strong>5</strong> (4 votes cast)</div><br />]]></description>
			<content:encoded><![CDATA[<p>These are links to the slides and video of Michael Caisse&#8217;s BoostCon 2010 talk:</p>
<p>slides: <a href="http://www.objectmodelingdesigns.com/boostcon10/">&lt;http://www.objectmodelingdesigns.com/boostcon10/&gt;</a><br />
video: <a href="http://blip.tv/file/4143337">&lt;http://blip.tv/file/4143337 &gt;</a></p>
<p>Enjoy!</p>
<blockquote><p>Machinery, sensors, equipment, client/server communications, even file formats&#8230; Parsing and producing communication streams is everywhere you look. Often these tasks are simple or small enough to tempt ad-hoc solutions. The Spirit 2.1 library provides a model that is simple enough to tackle those &#8220;quick hacks&#8221; and easily scales for full-featured AST generation.</p>
<p>This session will explore real-life experiences with the parser and generator (Qi/Karma) portions of the Spirit library. As we look at various small and medium-sized parsers/generators employed in various products we will establish some &#8220;rules-of-thumb&#8221; and guidelines for tackling the parser/generator domain with Qi/Karma. The session will end with the implementation of a usable XML parser and a simplified XPath-like node extractor.</p>
<p>The session will include some lecture and a lot of tutorial. Attendees will walk away with the knowledge and tools to begin parsing and generating with Spirit Qi/Karma.</p>
<p>—Michael Caisse</p></blockquote>
<br /><div><img src="http://boost-spirit.com/home/wp-content/plugins/gd-star-rating/gfx.php?value=3.5" /></div><div>Rating: 3.5/<strong>5</strong> (4 votes cast)</div><br />]]></content:encoded>
			<wfw:commentRss>http://boost-spirit.com/home/2010/12/03/using-boost-spirit-v2-qi-and-karma/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Multi-threaded Qi: 6 hours -&gt; 37 seconds</title>
		<link>http://boost-spirit.com/home/2010/11/07/multi-threaded-qi-6-hours-37-seconds/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=multi-threaded-qi-6-hours-37-seconds</link>
		<comments>http://boost-spirit.com/home/2010/11/07/multi-threaded-qi-6-hours-37-seconds/#comments</comments>
		<pubDate>Sun, 07 Nov 2010 07:54:23 +0000</pubDate>
		<dc:creator>Joel de Guzman</dc:creator>
				<category><![CDATA[Mailing List]]></category>
		<category><![CDATA[User Experience]]></category>
		<category><![CDATA[Qi]]></category>

		<guid isPermaLink="false">http://boost-spirit.com/home/?p=1161</guid>
		<description><![CDATA[The Spirit mailing list is still the place where active discussion takes place. I will be posting some excerpts from the mailing list here every once in a while. Here&#8217;s an interesting post from Leo Goodstadt: Are Qi parsers thread-safe? The answer of course is yes I have been trying to speed up some parsing [...]<br /><div><img src="http://boost-spirit.com/home/wp-content/plugins/gd-star-rating/gfx.php?value=5.0" /></div><div>Rating: 5.0/<strong>5</strong> (8 votes cast)</div><br />]]></description>
			<content:encoded><![CDATA[<p>The Spirit mailing list is still the place where active discussion takes place. I will be posting some excerpts from the mailing list here every once in a while. Here&#8217;s an interesting post from Leo Goodstadt:<br />
Are Qi parsers thread-safe?</p>
<blockquote><p><em>The answer of course is yes</em></p></blockquote>
<p>I have been trying to speed up some parsing code going through around 25 GB of data. This had been taking up 6 hours using Python code. Re-writing it using Qi had taken it down to 4 minutes. And finally, with the help of Intel Threading Building Blocks, I am down to 37 seconds or a &gt; 500x speedup!<br />
<span id="more-1161"></span><br />
The final code runs optimally with around 15 threads. The process seems to be entirely bounded by the physical limits of pulling 25 Gb off the hard disk raid over the network.<br />
Intel TBB works really very well with Spirit / Qi.<br />
I divide the parsing tasks into three parts:</p>
<ol>
<li>The data is in a one-item-per-line format, so I can divide up the file as it is being read into chunks of lines of around (&lt;=) 64 kb at a time. This is a serial process.</li>
<li>These are then parsed by Qi and analysed in parallel.</li>
<li>TBB then takes the output from (2) and feeds them serially in order for step (3).</li>
</ol>
<p>I have to write some classes to provide a set of reusable buffers for the data flow through the pipeline to avoid lots of memory allocations and thrashing the cache.</p>
<p>At the moment, each thread has its own lexer. Is there data held statically within each instance of the lexer or are they thread-safe?</p>
<blockquote><p><em>Hartmut replies: There is no static data, everything should be perfectly thread safe as long as you do not share either the lexer objects or the iterators between threads, while simultaneously accessing them.</em></p></blockquote>
<p>I should say, thank you so much for Qi. It is the one library I can point to in c++ which trumps anything out there for any other language.</p>
<p>Leo Goodstadt</p>
<br /><div><img src="http://boost-spirit.com/home/wp-content/plugins/gd-star-rating/gfx.php?value=5.0" /></div><div>Rating: 5.0/<strong>5</strong> (8 votes cast)</div><br />]]></content:encoded>
			<wfw:commentRss>http://boost-spirit.com/home/2010/11/07/multi-threaded-qi-6-hours-37-seconds/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Integer to String Conversion: Karma fastest again</title>
		<link>http://boost-spirit.com/home/2010/03/09/integer-to-string-conversion-karma-fastest-again/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=integer-to-string-conversion-karma-fastest-again</link>
		<comments>http://boost-spirit.com/home/2010/03/09/integer-to-string-conversion-karma-fastest-again/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 13:24:01 +0000</pubDate>
		<dc:creator>Hartmut Kaiser</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[User Experience]]></category>
		<category><![CDATA[Karma]]></category>

		<guid isPermaLink="false">http://boost-spirit.com/home/?p=1031</guid>
		<description><![CDATA[Tino Didriksin published yet another speed comparison of different ways to convert an integer into a string (see his blog A howl on the Wind&#8230;). And again, Karma turns out to be the leader of the pack by being upto 10 times faster than the other tested methods. This nicely supports our own measurements (see here). Thanks [...]<br /><div><img src="http://boost-spirit.com/home/wp-content/plugins/gd-star-rating/gfx.php?value=5.0" /></div><div>Rating: 5.0/<strong>5</strong> (3 votes cast)</div><br />]]></description>
			<content:encoded><![CDATA[<p>Tino Didriksin published yet another speed comparison of different ways to convert an integer into a string (see his blog <a title="A howl on the Wind..." href="http://tinodidriksen.com/2010/02/07/cpp-convert-int-to-string-speed/">A howl on the Wind&#8230;</a>). And again, <em>Karma</em> turns out to be the leader of the pack by being upto 10 times faster than the other tested methods. This nicely supports our own measurements (see <a href="http://www.boost.org/doc/libs/1_42_0/libs/spirit/doc/html/spirit/karma/performance_measurements/numeric_performance/int_performance.html">here</a>). Thanks Tino!</p>
<br /><div><img src="http://boost-spirit.com/home/wp-content/plugins/gd-star-rating/gfx.php?value=5.0" /></div><div>Rating: 5.0/<strong>5</strong> (3 votes cast)</div><br />]]></content:encoded>
			<wfw:commentRss>http://boost-spirit.com/home/2010/03/09/integer-to-string-conversion-karma-fastest-again/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Karma &#8216;dramatically faster than boost::format&#8217;</title>
		<link>http://boost-spirit.com/home/2010/01/12/karma-dramatically-faster-than-boostformat/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=karma-dramatically-faster-than-boostformat</link>
		<comments>http://boost-spirit.com/home/2010/01/12/karma-dramatically-faster-than-boostformat/#comments</comments>
		<pubDate>Tue, 12 Jan 2010 22:10:15 +0000</pubDate>
		<dc:creator>Hartmut Kaiser</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[User Experience]]></category>
		<category><![CDATA[Karma]]></category>

		<guid isPermaLink="false">http://boost-spirit.com/home/2010/01/12/karma-dramatically-faster-than-boostformat/</guid>
		<description><![CDATA[Stephan Menzel wrote today on the Boost developer mailing list (see here): Lacking boost.log we created or own logging class which is basically an as-simple-as-possible Syslog client. (I like to process and accumulate there). It used to be boost.format to assemble the messages which proved slower than log4cxx. With Spirit 2.1 in 1.41 however we [...]<br /><div><img src="http://boost-spirit.com/home/wp-content/plugins/gd-star-rating/gfx.php?value=0.0" /></div><div>Rating: 0.0/<strong>5</strong> (0 votes cast)</div><br />]]></description>
			<content:encoded><![CDATA[<p>Stephan Menzel wrote today on the Boost developer mailing list (see <a href="http://old.nabble.com/-log--Release-Candidate-4-released-tc27076612.html#a27132978">here</a>):</p>
<blockquote><p>Lacking boost.log we created or own logging class which is basically an as-simple-as-possible Syslog client. (I like to process and accumulate there). It used to be boost.format to assemble the messages which proved slower than log4cxx. With Spirit 2.1 in 1.41 however we changed to use a Karma message generator for this purpose which improved speed dramatically.</p></blockquote>
<p>Thanks Stephan! We are happy to hear that!</p>
<p>If you have other success stories while using Spirit, we would love to hear about your experience. Just leave a comment below, we happily will write about it.</p>
<br /><div><img src="http://boost-spirit.com/home/wp-content/plugins/gd-star-rating/gfx.php?value=0.0" /></div><div>Rating: 0.0/<strong>5</strong> (0 votes cast)</div><br />]]></content:encoded>
			<wfw:commentRss>http://boost-spirit.com/home/2010/01/12/karma-dramatically-faster-than-boostformat/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

