<?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>teideal glic deisbhéalach &#187; Uncategorized</title>
	<atom:link href="http://www.serpentine.com/blog/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.serpentine.com/blog</link>
	<description>Bryan O&#039;Sullivan&#039;s blog</description>
	<lastBuildDate>Thu, 01 Dec 2011 16:53:49 +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>Here be dragons: advances in problems you didn&#8217;t even know you had</title>
		<link>http://www.serpentine.com/blog/2011/06/29/here-be-dragons-advances-in-problems-you-didnt-even-know-you-had/</link>
		<comments>http://www.serpentine.com/blog/2011/06/29/here-be-dragons-advances-in-problems-you-didnt-even-know-you-had/#comments</comments>
		<pubDate>Wed, 29 Jun 2011 07:27:08 +0000</pubDate>
		<dc:creator>Bryan O'Sullivan</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.serpentine.com/blog/?p=844</guid>
		<description><![CDATA[Here&#8217;s something I bet you never think about, and for good reason: how are floating-point numbers rendered as text strings? This is a surprisingly tough problem, but it&#8217;s been regarded as essentially solved since about 1990.Prior to Steele and White&#8217;s &#34;How to print floating-point numbers accurately&#34;, implementations of printf and similar rendering functions did their [...]]]></description>
			<content:encoded><![CDATA[<p
>Here&#8217;s something I bet you never think about, and for good reason: how are floating-point numbers rendered as text strings? This is a surprisingly tough problem, but it&#8217;s been regarded as essentially solved since about 1990.</p
><p
>Prior to Steele and White&#8217;s &quot;<a href="http://portal.acm.org/citation.cfm?id=93559"
  >How to print floating-point numbers accurately</a
  >&quot;, implementations of <code
  >printf</code
  > and similar rendering functions did their best to render floating point numbers, but there was wide variation in how well they behaved. A number such as 1.3 might be rendered as 1.29999999, for instance, or if a number was put through a feedback loop of being written out and its written representation read back, each successive result could drift further and further away from the original.</p
><p
>Steele and White effectively solved the problem with a clever algorithm named &quot;Dragon4&quot; (the fourth version of the &quot;Dragon&quot; algorithm, which acquired its name because the authors were inspired to obscure puns by Heighway's <a href="http://en.wikipedia.org/wiki/Dragon_curve"
  >dragon curve</a
  >).</p
><p
>The Dragon4 algorithm spread quickly across language runtimes, such that few programmers today understand that this was ever a problem, much less how hairy it was (and is). Indeed, prior to last year, there was almost no activity in this area: two papers proposed widely used refinements to Dragon4, and that was about it. (Alas, the problem was originally solved around a decade before Steele and White published their work, but nobody noticed. If you have a clever idea and sufficient chutzpah, try to enlist Guy Steele as a coauthor. Your work will be read.)</p
><p
>But how solved was the problem? Dragon4 and its derivatives are complicated and tricky, and they have a hefty performance cost, since they rely on arbitrary-precision integer arithmetic to compute their results. There might be a significant performance improvement to be gained if someone could figure out how to use native machine integers instead.</p
><p
>In 2010, Florian Loitsch published a wonderful paper in PLDI, &quot;<a href="http://florian.loitsch.com/publications/dtoa-pldi2010.pdf?attredirects=0"
  >Printing floating-point numbers quickly and accurately with integers</a
  >&quot;, which represents the biggest step in this field in 20 years: he mostly figured out how to use machine integers to perform accurate rendering! Why do I say &quot;mostly&quot;? Because although Loitsch's &quot;Grisu3&quot; algorithm is very fast, it <em
  >gives up</em
  > on about 0.5% of numbers, in which case you have to fall back to Dragon4 or a derivative.</p
><p
>If you're a language runtime author, the Grisu algorithms are a big deal: Grisu3 is about 5 times faster than the algorithm used by <code
  >printf</code
  > in GNU libc, for instance. A few language implementors have already taken note: Google hired Loitsch, and the Grisu family acts as the default rendering algorithms in both the V8 and Mozilla Javascript engines (replacing David Gay's 17-year-old <code
  >dtoa</code
  > code). Loitsch has kindly released implementations of his Grisu algorithms as a library named <a href="http://code.google.com/p/double-conversion"
  ><code
    >double-conversion</code
    ></a
  >.</p
><p
>And of course I can't talk about performance without mentioning Haskell somewhere :-) I've taken Loitsch's library and written a <a href="http://hackage.haskell.org/package/double-conversion"
  >Haskell interface</a
  >, which I've measured to be 30 times faster than the default renderer used in the Haskell runtime libraries. This has some nice knock-on effects: my <a href="http://hackage.haskell.org/package/aeson"
  ><code>aeson</code> JSON library</a
  > is now 10 times faster at rendering big arrays of floating point numbers, for instance. I accidentally noticed in the course of that work that my Haskell <a href="http://hackage.haskell.org/package/text"
  ><code
    >text</code
    > Unicode library</a
  >'s UTF-8 encoder wasn't as fast as it could be, so I improved its performance by about 50% along the way. Hooray for faster code!</p
><p
>(By the way, the punnery in algorithm naming continues: the Grisu algorithms are named for <a href="http://de.wikipedia.org/wiki/Grisu,_der_kleine_Drache"
  >GrisÃ¹, the little dragon</a
  >.)</p
>]]></content:encoded>
			<wfw:commentRss>http://www.serpentine.com/blog/2011/06/29/here-be-dragons-advances-in-problems-you-didnt-even-know-you-had/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>text 0.10.0.0 is here</title>
		<link>http://www.serpentine.com/blog/2010/10/22/text-0-10-0-0-is-here/</link>
		<comments>http://www.serpentine.com/blog/2010/10/22/text-0-10-0-0-is-here/#comments</comments>
		<pubDate>Fri, 22 Oct 2010 05:36:29 +0000</pubDate>
		<dc:creator>Bryan O'Sullivan</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.serpentine.com/blog/?p=756</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[
]]></content:encoded>
			<wfw:commentRss>http://www.serpentine.com/blog/2010/10/22/text-0-10-0-0-is-here/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Haskell in the Real World discussion at CUFP</title>
		<link>http://www.serpentine.com/blog/2010/08/25/haskell-in-the-real-world-discussion-at-cufp/</link>
		<comments>http://www.serpentine.com/blog/2010/08/25/haskell-in-the-real-world-discussion-at-cufp/#comments</comments>
		<pubDate>Wed, 25 Aug 2010 17:20:20 +0000</pubDate>
		<dc:creator>Bryan O'Sullivan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.serpentine.com/blog/?p=652</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[
]]></content:encoded>
			<wfw:commentRss>http://www.serpentine.com/blog/2010/08/25/haskell-in-the-real-world-discussion-at-cufp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>What&#8217;s in a parser? Attoparsec rewired (2/2)</title>
		<link>http://www.serpentine.com/blog/2010/03/03/whats-in-a-parser-attoparsec-rewired-2/</link>
		<comments>http://www.serpentine.com/blog/2010/03/03/whats-in-a-parser-attoparsec-rewired-2/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 18:03:27 +0000</pubDate>
		<dc:creator>Bryan O'Sullivan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.serpentine.com/blog/?p=584</guid>
		<description><![CDATA[In my first of this pair of articles, I laid out some of the qualities I've been looking for in a parsing library.Before I dive back into detail, I want to show off some numbers. The new Attoparsec code is fast.What did I benchmark? I captured some real HTTP GET requests from a live public [...]]]></description>
			<content:encoded><![CDATA[<p
>In my <a href="http://www.serpentine.com/blog/2010/03/03/whats-in-a-parsing-library-1/"
  >first of this pair of articles</a
  >, I laid out some of the qualities I've been looking for in a parsing library.</p
><p
>Before I dive back into detail, I want to show off some numbers. The new Attoparsec code is <em
  >fast</em
  >.</p
><p
><img src="http://chart.apis.google.com/chart?cht=bvs&amp;chs=340x200&amp;chd=t:260,0,0,0,0|0,471,0,0,0|0,0,17037,0,0|0,0,0,23753,0|0,0,0,0,36753&amp;chds=0,40000&amp;chco=4D89F9|894DF9|F94D89|4DB989|1969FD&amp;chdl=260+ms:+http_parser|471+ms:+Attoparsec|17037+ms:+Parsec+3+CPS|23753+ms:+Lazy+Parsec+3+CPS|36753+ms:+Parsec+3&amp;chxt=y&amp;chxl=0:||10|20|30|40&amp;chtt=Time+to+parse+45,668|HTTP+GET+requests" alt="Performance"
   /></p
><p
>What did I benchmark? I captured some real HTTP GET requests from a live public web server, averaging 431 bytes per request. I chucked them into a file, and measured the time needed to parse the entire contents of the file with the following libraries:</p
><ul
><li
  ><p
    >Ryan Dahl's <a href="http://github.com/ry/http-parser"
      >http-parser</a
      > library, which is 1,672 lines of hand-rolled C craziness. I mean "craziness" in a special sort of awed way, with that hushed voice you reserve for the guy who builds the scale model of Neuschwanstein Castle in matchsticks. The library's heritage is closely based on the Ragel-generated parser used by Mongrel. This library is a fair approximation to about as fast as you can get, since it's been tuned for just one purpose. I wrote a smallish, but reasonably realistic, <a href="http://bitbucket.org/bos/attoparsec/src/tip/examples/rfc2616.c"
      >driver program</a
      > to wire it up to file-based data, adding another 210 lines of code.</p
    ></li
  ><li
  ><p
    >An Attoparsec-based <a href="http://bitbucket.org/bos/attoparsec/src/tip/examples/RFC2616.hs"
      >HTTP request parser</a
      >, 54 lines long, with about 30 lines of <a href="http://bitbucket.org/bos/attoparsec/src/tip/examples/TestRFC2616.hs"
      >driver program</a
      >. (Attoparsec itself is about 900 lines of code.)</p
    ></li
  ><li
  ><p
    >Several <a href="http://bitbucket.org/bos/attoparsec/src/tip/examples/Parsec_RFC2616.hs"
      >Parsec-3-based parsers</a
      >, which are almost identical in length to the Attoparsec-based version.</p
    ></li
  ></ul
><p
>The Parsec 3 parsers come in three varieties:</p
><ul
><li
  ><p
    >The fastest uses a patch that Antoine Latter wrote to switch Parsec 3's internal machinery over to using continuation passing style (CPS). This parser uses <code
      >ByteString</code
      > for input, and reads the entire 18.8MB file in one chunk.</p
    ></li
  ><li
  ><p
    >Next is the same parser, using lazy <code
      >ByteString</code
      > I/O to read the file in 64KB chunks. This costs about 40% in performance, but is almost mandatory to maintain a reasonable memory footprint on large inputs.</p
    ></li
  ><li
  ><p
    >In last place is the official version of Parsec 3, reading the input in one chunk. (Reading lazily still costs an additional 40%, but I didn't want to further clutter the chart with more big numbers.)</p
    ></li
  ></ul
><p
>What's interesting to me is that the tiny Attoparsec-based parser, which is more or less a transliteration of the relevant parts of <a href="http://www.w3.org/Protocols/rfc2616/rfc2616.html"
  >RFC 2616</a
  >, is so fast.</p
><p
>I went back and remeasured performance of the Attoparsec and C parsers on a larger data set (295,568 URLs), and got these numbers:</p
><ul
><li
  ><p
    >Attoparsec: 2.889 seconds, or 102,308 requests/second</p
    ></li
  ><li
  ><p
    >C: 1.614 seconds, or 183,128 requests/second</p
    ></li
  ></ul
><p
>That clocks the Attoparsec-based parser at about 56% the speed of the C parser. Not bad, given that it's about 3.2% the number of lines of code!</p
><p
>Of course there are tradeoffs involved here.</p
><ul
><li
  ><p
    >Parsec 3 emits much more friendly error messages, and can handle many different input types. Attoparsec, being aimed at plumbing-oriented network protocols, considers friendly error messages to not be worth the effort, and is specialised to the arrays of bytes you get straight off the network.</p
    ></li
  ><li
  ><p
    >Parsec 3 requires all of its input to be available when the parser is run (either in one large chunk or via lazy I/O). If Attoparsec has insufficient data to return a complete result, it hands back a continuation that you provide extra data to. This eliminates the need for lazy I/O and any additional buffering, and makes for a beautiful, pure API that doesn't care what its input source is.</p
    ></li
  ></ul
><p
>The memory footprint of the Attoparsec-based parser is small: it will run in 568KB of heap on my 64-bit laptop. The smallest heap size that the Parsec 3 parser can survive in isn't all that much larger: with lazily read input, it will run in a 750KB heap.</p
><p
>Overall, this is yet another instance where a little careful attention to performance yields very exciting results. Personally, I'd be quite happy to trade a 97% reduction in code size for such a small performance hit, especially given the clarity, ease of use, and flexibility of the resulting code. (The <code
  >http_parser</code
  > API is frankly not so much fun to use, even though I completely understand the motivation behind it.)</p
>]]></content:encoded>
			<wfw:commentRss>http://www.serpentine.com/blog/2010/03/03/whats-in-a-parser-attoparsec-rewired-2/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>What&#8217;s in a parsing library? (1/2)</title>
		<link>http://www.serpentine.com/blog/2010/03/03/whats-in-a-parsing-library-1/</link>
		<comments>http://www.serpentine.com/blog/2010/03/03/whats-in-a-parsing-library-1/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 07:12:28 +0000</pubDate>
		<dc:creator>Bryan O'Sullivan</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.serpentine.com/blog/?p=574</guid>
		<description><![CDATA[My goal in working on the new GHC I/O manager has been to get the Haskell network stack into a state where it could be used to attack high-performance and scalable networking problems, domains in which it has historically been weak.While it's encouraging to have an excellent networking stack (Johan and I now have this [...]]]></description>
			<content:encoded><![CDATA[<p
>My goal in working on the <a href="http://www.serpentine.com/blog/2010/01/22/new-ghc-io-manager-first-benchmark-numbers/"
  >new GHC I/O manager</a
  > has been to get the Haskell network stack into a state where it could be used to attack high-performance and scalable networking problems, domains in which it has historically been weak.</p
><p
>While it's encouraging to have an excellent networking stack (Johan and I now have this thoroughly in hand), the next thing I'd look for is libraries to help build networked applications. One of the fundamental things that such apps need to do well is parse data, be it received from the network or read from files.</p
><p
>The Haskell parsing library of first resort has for years been <a href="http://www.haskell.org/haskellwiki/Parsec"
  >Parsec</a
  >. While other capable libraries exist (e.g. <a href="http://hackage.haskell.org/package/polyparse"
  >polyparse</a
  > and <a href="http://hackage.haskell.org/package/uu-parsinglib"
  >uu-parsinglib</a
  >), they don't appear to see much use.</p
><p
>As appealing as Parsec's API is, it has a few problems:</p
><ul
><li
  ><p
    >Parsec 2 is slow, and it has high memory overhead, due to its use of Haskell's <code
      >String</code
      > type for tokens. Parsec 3 can use the more efficient <code
      >ByteString</code
      > type (which is in any case much more appropriate for networked applications that deal in octets), but it achieves this flexibility at the cost of being even slower than Parsec 2.</p
    ></li
  ><li
  ><p
    >Parsec's API demands that all of a parser's input be available at once. People usually work around this by feeding a Parsec parser with lazily read data, but lazy I/O is at odds with my goal of writing solid networked code.</p
    ></li
  ></ul
><p
>What properties should a parsing library for networked applications ideally possess? There are a few obvious desiderata that have been well known for years. For example, it's important to have an appealing API and programming model. Parsec squarely fits this desire.</p
><p
>Performance is also a big consideration. Ideally, a parsing library would be fast enough that you wouldn't feel any real need for either of the following:</p
><ul
><li
  ><p
    >A few weeks to write an insane hand-bummed parser.</p
    ></li
  ><li
  ><p
    >Mechanical parser generators or lexers (e.g. <a href="http://www.haskell.org/happy/"
      >happy</a
      > or <a href="http://www.haskell.org/alex/"
      >alex</a
      >).</p
    ></li
  ></ul
><p
>There are some additional important constraints on a realistic library: it must fit well into a highly concurrent networked world full of unreliable, hostile and incompetent clients.</p
><ul
><li
  ><p
    >High concurrency levels demand a low per-connection memory footprint.</p
    ></li
  ><li
  ><p
    >The need to cope with poorly behaved clients requires that applications must be able to throttle connections that are too busy, or kill connections that are too slow or attempting to consume too many server resources. A good parsing library will not get in the way of these needs.</p
    ></li
  ></ul
><p
>A few years ago, I made a few half-hearted attempts to write a specialised version of Parsec, which I eventually named <a href="http://hackage.haskell.org/package/attoparsec"
  >Attoparsec</a
  >.</p
><p
>I began with a stripped-down Parsec that was specialised to accept <code
  >ByteString</code
  > input. I then extended the API to allow a parser to consume small chunks of input at a time.</p
><p
>Because I wasn't using Attoparsec &quot;in anger&quot; at the time, I made sure that my library worked (more or less), but I was not measuring its performance.</p
><p
>In late January of this year, I began to think about using Attoparsec as the parser for a simple HTTP server that I could use to benchmark our new GHC I/O manager code. Clearly, I'd want the parser to perform well, or it would distort my numbers rather badly.</p
><p
>By coincidence, <a href="http://johnmacfarlane.net/"
  >John MacFarlane</a
  > emailed me around the same time, with disturbing findings: he'd tried Attoparsec, and found its performance to be <em
  >terrible</em
  >! In fact, it was 4 to 20 times <em
  >slower</em
  > than plain Parsec with his experimental parser and test data. Clearly, I had some hard work to look forward to.</p
><p
>Happily, that work is now almost complete, and I am pleased with the results. In the next post, I'll have some details of what this all entails.</p
>]]></content:encoded>
			<wfw:commentRss>http://www.serpentine.com/blog/2010/03/03/whats-in-a-parsing-library-1/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Minuscule linkscrape of mischief</title>
		<link>http://www.serpentine.com/blog/2010/01/30/massive-linkscrape-of-mischievous-doom/</link>
		<comments>http://www.serpentine.com/blog/2010/01/30/massive-linkscrape-of-mischievous-doom/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 00:32:26 +0000</pubDate>
		<dc:creator>Bryan O'Sullivan</dc:creator>
				<category><![CDATA[slice-o-life]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[lolwut]]></category>

		<guid isPermaLink="false">http://www.serpentine.com/blog/?p=564</guid>
		<description><![CDATA[While I&#8217;ve been in my corner hacking on low-level Haskell nonsense, apparently someone figured out how to make the internets more better. To wit, a few judiciously curated sources of visual edification: for great justice unhappy hipsters riot right click]]></description>
			<content:encoded><![CDATA[<p>While I&#8217;ve been in my corner hacking on low-level Haskell nonsense, apparently someone figured out how to make the internets more better.</p>
<p>To wit, a few judiciously curated sources of visual edification:</p>
<p><a href="http://forgreatjustice.tumblr.com/post/359166403/dont-worry-im-from-the-internet"><img src="http://27.media.tumblr.com/tumblr_kwz785G6N01qalbabo1_500.jpg" alt="I'm from the internet" /></a>
<br/><a href="http://forgreatjustice.tumblr.com/">for great justice</a></p>
<p><a href="http://unhappyhipsters.com/post/354725045/the-octopus-was-full-of-judgment-dwell-october"><img src="http://27.media.tumblr.com/tumblr_kwvcm5BExl1qam6ylo1_500.jpg" alt="The octopus was full of judgment" /></a><br/>
<a href="http://unhappyhipsters.com/">unhappy hipsters</a></p>
<p><a href="http://riotclitshave.livejournal.com/1693322.html"><img src="http://riotclitshave.com/2010.01/megan-dscf2656jpg.jpeg" alt="Ooooooh" /></a><br/>
<a href="http://riotclitshave.livejournal.com/">riot right click</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.serpentine.com/blog/2010/01/30/massive-linkscrape-of-mischievous-doom/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>New GHC I/O manager, first sets of benchmark numbers</title>
		<link>http://www.serpentine.com/blog/2010/01/22/new-ghc-io-manager-first-benchmark-numbers/</link>
		<comments>http://www.serpentine.com/blog/2010/01/22/new-ghc-io-manager-first-benchmark-numbers/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 07:28:31 +0000</pubDate>
		<dc:creator>Bryan O'Sullivan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.serpentine.com/blog/?p=549</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[
]]></content:encoded>
			<wfw:commentRss>http://www.serpentine.com/blog/2010/01/22/new-ghc-io-manager-first-benchmark-numbers/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Progress on GHC&#8217;s I/O manager</title>
		<link>http://www.serpentine.com/blog/2010/01/11/progress-on-ghcs-io-manager/</link>
		<comments>http://www.serpentine.com/blog/2010/01/11/progress-on-ghcs-io-manager/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 08:52:53 +0000</pubDate>
		<dc:creator>Bryan O'Sullivan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.serpentine.com/blog/?p=544</guid>
		<description><![CDATA[Over the past couple of weeks, I have been working with Johan Tibbell on an event library to use for replacing GHC&#8217;s existing I/O manager. The work has been progressing rather nicely: I now have both the epoll and kqueue back ends working, while Johan has been focusing on a fast priority queue data structure [...]]]></description>
			<content:encoded><![CDATA[<p>Over the past couple of weeks, I have been working with Johan Tibbell on an event library to use for replacing <a href="http://www.serpentine.com/blog/2009/12/17/making-ghcs-io-manager-more-scalable/">GHC&#8217;s existing I/O manager</a>. The work has been progressing rather nicely: I now have both the epoll and kqueue back ends working, while Johan has been focusing on a fast priority queue data structure for managing timeouts.</p>

<p>We&#8217;ve been working from a pair of git repositories:</p>
<ul>
<li>Johan&#8217;s is at <a href="http://github.com/tibbe/event">http://github.com/tibbe/event</a></li>
<li>Mine is at <a href="http://github.com/bos/event">http://github.com/bos/event</a></li>
</ul>
</li>

<p>(Incidentally, I&#8217;m using the excellent <a href="http://hg-git.github.com/">hg-git plugin for Mercurial</a>, which has allowed me to continue to avoid using git. It&#8217;s been working very well. Many thanks to Scott Chacon and Augie Fackler for their work on it!)</p>

<p>Of course, now that we have the basic plumbing working, I have a few numbers to report. These are all for sending and receiving 1,000,000 messages over Unix pipes.</p>
<ul>
<li>On 64-bit Linux, I can easily create 100,000 pipes (i.e. 200,000 file descriptors), and pass all messages through them in 6.69 seconds.</li>
<li>Under 32-bit Snow Leopard, for some reason I can&#8217;t create more than 2,048 pipes. Passing all messages takes 7.41 seconds.
<li>With the same 2,048 pipes under Linux, the time required is 4.15 seconds.</li>
<li>Under Linux, if I try to create a very large number of pipes, I get an error message &#8220;VFS: file-max limit 291248 reached&#8221;, and as I just discovered, the machine starts to misbehave. Good times!</li>
</ul>

<p>These are pretty gratifying numbers to have. This has been a very fun project so far, both in the technical parts and the dealings with the other people involved. I&#8217;m looking forward to continuing to work on it with Johan and others!</p>]]></content:encoded>
			<wfw:commentRss>http://www.serpentine.com/blog/2010/01/11/progress-on-ghcs-io-manager/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Making GHC&#8217;s I/O manager more scalable</title>
		<link>http://www.serpentine.com/blog/2009/12/17/making-ghcs-io-manager-more-scalable/</link>
		<comments>http://www.serpentine.com/blog/2009/12/17/making-ghcs-io-manager-more-scalable/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 06:32:14 +0000</pubDate>
		<dc:creator>Bryan O'Sullivan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.serpentine.com/blog/?p=540</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[
]]></content:encoded>
			<wfw:commentRss>http://www.serpentine.com/blog/2009/12/17/making-ghcs-io-manager-more-scalable/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>The performance of Data.Text</title>
		<link>http://www.serpentine.com/blog/2009/12/10/the-performance-of-data-text/</link>
		<comments>http://www.serpentine.com/blog/2009/12/10/the-performance-of-data-text/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 00:17:20 +0000</pubDate>
		<dc:creator>Bryan O'Sullivan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.serpentine.com/blog/?p=500</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[
]]></content:encoded>
			<wfw:commentRss>http://www.serpentine.com/blog/2009/12/10/the-performance-of-data-text/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

