<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Attractive Chaos &#187; programming</title>
	<atom:link href="http://attractivechaos.wordpress.com/tag/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://attractivechaos.wordpress.com</link>
	<description>Just another WordPress.com weblog</description>
	<lastBuildDate>Tue, 29 Sep 2009 22:22:13 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='attractivechaos.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/3aaf4ad34bfdf87dcbb70d9e3cbd326d?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Attractive Chaos &#187; programming</title>
		<link>http://attractivechaos.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://attractivechaos.wordpress.com/osd.xml" title="Attractive Chaos" />
		<item>
		<title>Another Look at my old Benchmark</title>
		<link>http://attractivechaos.wordpress.com/2008/10/07/another-look-at-my-old-benchmark/</link>
		<comments>http://attractivechaos.wordpress.com/2008/10/07/another-look-at-my-old-benchmark/#comments</comments>
		<pubDate>Tue, 07 Oct 2008 12:02:47 +0000</pubDate>
		<dc:creator>attractivechaos</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[benchmark]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[cpp]]></category>
		<category><![CDATA[myprog]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://attractivechaos.wordpress.com/?p=586</guid>
		<description><![CDATA[This is a follow-up of my previous post. Here I change the table to several charts. Hope it seems more friendly to readers. You can find the links to these libraries in that table. Their source codes, including my testing code, are available here. You may also want to see my previous posts in the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=586&subd=attractivechaos&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>This is a follow-up of my previous post. Here I change <a href="http://attractivechaos.awardspace.com/udb.html">the table</a> to several charts. Hope it seems more friendly to readers. You can find the links to these libraries in that table. Their source codes, including my testing code, are available <a href="http://attractivechaos.awardspace.com/download/udb-latest.tar.bz2">here</a>. You may also want to see my previous posts in the last few days for my interpretation to the results.</p>
<p>On C string (char*) keys, I fail to use JE_rb_old and JE_rb_new to get the correct result on Mac and so they are not showed in the charts. I would really appreciate if someone may give me the correct implementation using these libraries. In addition, tr1_unordered_map uses a lot of memory according to my program. The memory for string keys are faked.</p>
<p>For conveniece, here are some brief descriptions of these libraries (with no order):</p>
<ul>
<li>google_dense and google_sparse: <a href="http://code.google.com/p/google-sparsehash/">google&#8217;s sparsehash library</a>. Google_dense is fast but memory hungery while google_sparse is the opposite.</li>
<li>sgi_hash_map and sgi_map: <a href="http://www.sgi.com/tech/stl/">SGI&#8217;s STL</a> that comes with g++-4. The backend of sgi_map is a three-pointer red-black tree.</li>
<li>tr1::unordered_map: GCC&#8217;s TR1 library that comes with g++-4. It implements a hash table.</li>
<li>rdestl::hash_map: from <a href="http://code.google.com/p/rdestl/">RDESTL</a>, another implementation of STL.</li>
<li><a href="http://uthash.sourceforge.net/">uthash</a>: a hash library in C</li>
<li>JG_btree: <a href="http://resnet.uoregon.edu/~gurney_j/jmpc/btree.html">John-Mark Gurney&#8217;s btree library</a>.</li>
<li>JE_rb_new, JE_rb_old, JE_trp_hash and JE_trp_prng: <a href="http://www.canonware.com/~ttt/2008/07/treaps-versus-red-black-trees.html">Jason Evans&#8217; binary search tree libraries</a>. JE_rb_new implements a left-leaning red-black tree; JE_rb_old a three-pointer red-black tree; both JE_trp_hash and JE_trp_prng implement treaps but with different strategies on randomness.</li>
<li>libavl_rb, libavl_prb, libavl_avl and libavl_bst: from <a href="http://www.stanford.edu/~blp/avl/">GNU libavl</a>. They implment a two-pointer red-black tree, a three-pointer red-black tree, an AVL tree and a unbalanced binary search tree, respectively.</li>
<li>NP_rbtree and NP_splaytree: <a href="http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/sys/tree.h">Niels Provos&#8217; tree library</a> for FreeBSD. A three-pointer red-black tree and a splay tree.</li>
<li>TN_rbtree: <a href="http://www.darkridge.com/~jpr5/archive/alg/node21.html">Thomas Niemann&#8217;s red-black tree</a>. I ported it to C++.</li>
<li>sglib_rbtree: from <a href="http://sglib.sourceforge.net/">SGLIB</a>. It implements a two-pointer recursive red-black tree (all the other binary search trees are implemented without recursion).</li>
<li>libavl_avl_cpp, libavl_rb_cpp and libavl_rb_cpp2: incomplete C++ version of libavl (no iterator), ported by me. Libavl_rb_cpp2 further uses the same technique in JE_rb_new to save the color bit. Source codes available in the package.</li>
<li><a href="http://attractivechaos.awardspace.com/khash.h.html">khash</a> and <a href="http://attractivechaos.awardspace.com/kbtree.h.html">kbtree</a>: my hash table and B-tree implementation. kbtree is based on JG_rbtree.</li>
</ul>
<p><a href="http://klib.sourceforge.net/images/udb-int-cpu.png"><img class="alignnone size-full wp-image-622" title="udb-int-cpu" src="http://klib.sourceforge.net/images/udb-int-cpu.png" alt="" width="542" height="309" /></a></p>
<p><a href="http://klib.sourceforge.net/images/udb-int-mem.png"><img class="alignnone size-full wp-image-623" title="udb-int-mem" src="http://klib.sourceforge.net/images/udb-int-mem.png" alt="" width="542" height="309" /></a></p>
<p><a href="http://klib.sourceforge.net/images/udb-str-cpu.png"><img class="alignnone size-full wp-image-624" title="udb-str-cpu" src="http://klib.sourceforge.net/images/udb-str-cpu.png" alt="" width="542" height="308" /></a></p>
<p><a href="http://attractivechaos.files.wordpress.com/2008/10/udb-str-mem.png"><img class="alignnone size-full wp-image-625" title="udb-str-mem" src="http://klib.sourceforge.net/images/udb-str-mem.png" alt="" width="543" height="309" /></a></p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/attractivechaos.wordpress.com/586/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/attractivechaos.wordpress.com/586/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/attractivechaos.wordpress.com/586/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/attractivechaos.wordpress.com/586/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/attractivechaos.wordpress.com/586/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/attractivechaos.wordpress.com/586/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/attractivechaos.wordpress.com/586/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/attractivechaos.wordpress.com/586/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/attractivechaos.wordpress.com/586/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/attractivechaos.wordpress.com/586/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=586&subd=attractivechaos&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://attractivechaos.wordpress.com/2008/10/07/another-look-at-my-old-benchmark/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/047ebc7bb9ff37a0da844413856e92cb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">attractivechaos</media:title>
		</media:content>

		<media:content url="http://klib.sourceforge.net/images/udb-int-cpu.png" medium="image">
			<media:title type="html">udb-int-cpu</media:title>
		</media:content>

		<media:content url="http://klib.sourceforge.net/images/udb-int-mem.png" medium="image">
			<media:title type="html">udb-int-mem</media:title>
		</media:content>

		<media:content url="http://klib.sourceforge.net/images/udb-str-cpu.png" medium="image">
			<media:title type="html">udb-str-cpu</media:title>
		</media:content>

		<media:content url="http://klib.sourceforge.net/images/udb-str-mem.png" medium="image">
			<media:title type="html">udb-str-mem</media:title>
		</media:content>
	</item>
		<item>
		<title>Futher Discussion on Search Trees</title>
		<link>http://attractivechaos.wordpress.com/2008/09/28/futher-discussion-on-search-trees/</link>
		<comments>http://attractivechaos.wordpress.com/2008/09/28/futher-discussion-on-search-trees/#comments</comments>
		<pubDate>Sun, 28 Sep 2008 21:23:28 +0000</pubDate>
		<dc:creator>attractivechaos</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[benchmark]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[cpp]]></category>
		<category><![CDATA[myprog]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://attractivechaos.wordpress.com/?p=535</guid>
		<description><![CDATA[Over the weekend, I have done a more comprehensive benchmark of various libraries on search trees. Two AVL, seven red-black tree, one Splay tree, two treap implementations are involved, together with seven hash table libraries. As I need to present a big table, I have to write it in a free-style HTML page. You can [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=535&subd=attractivechaos&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Over the weekend, I have done a more comprehensive benchmark of various libraries on search trees. Two AVL, seven red-black tree, one Splay tree, two treap implementations are involved, together with seven hash table libraries. As I need to present a big table, I have to write it in a free-style HTML page. You can find the complete benchmark <a href="http://attractivechaos.awardspace.com/udb.html">here</a> and all the source codes <a href="http://attractivechaos.awardspace.com/download/udb-20080928.tar.bz2">here</a>. I only copy the &#8220;concluding remarks&#8221; in the benchmark page as follows:</p>
<ul>
<li>Hash table is preferred over search trees if we do not require order.</li>
<li>In applications similar to my example, B-tree is better than most of binary search trees in terms of both speed and memory.</li>
<li>AVL tree and red-black tree are the best general-purposed BSTs. They are very close in efficiency.</li>
<li>For pure C libraries, using macros is usually more efficient than using void* to achieve generic programming.</li>
</ul>
<p>You can find the result and much more discussions in <a href="http://attractivechaos.awardspace.com/udb.html">that page</a>. If you think the source codes or the design of benchmark can be improved, please leave comments here or send me E-mail. In addition, I failed to use several libraries and so you can see some blank in the table. I would also appreciate if someone could show me how to use those libraries correctly.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/attractivechaos.wordpress.com/535/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/attractivechaos.wordpress.com/535/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/attractivechaos.wordpress.com/535/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/attractivechaos.wordpress.com/535/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/attractivechaos.wordpress.com/535/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/attractivechaos.wordpress.com/535/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/attractivechaos.wordpress.com/535/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/attractivechaos.wordpress.com/535/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/attractivechaos.wordpress.com/535/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/attractivechaos.wordpress.com/535/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=535&subd=attractivechaos&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://attractivechaos.wordpress.com/2008/09/28/futher-discussion-on-search-trees/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/047ebc7bb9ff37a0da844413856e92cb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">attractivechaos</media:title>
		</media:content>
	</item>
		<item>
		<title>B-tree vs. Binary Search Tree</title>
		<link>http://attractivechaos.wordpress.com/2008/09/24/b-tree-vs-binary-search-tree/</link>
		<comments>http://attractivechaos.wordpress.com/2008/09/24/b-tree-vs-binary-search-tree/#comments</comments>
		<pubDate>Wed, 24 Sep 2008 22:38:45 +0000</pubDate>
		<dc:creator>attractivechaos</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[myprog]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://attractivechaos.wordpress.com/?p=507</guid>
		<description><![CDATA[When talking about in-memory search tree, we usually think of various binary search trees: red-black tree, AVL tree, treap, splay tree and so on. We do not often think of B-tree, as B-tree is commonly introduced as an on-disk data structure rather than in-memory one. Is B-tree also a good data structure for in-memory ordered [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=507&subd=attractivechaos&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>When talking about in-memory search tree, we usually think of various binary search trees: red-black tree, AVL tree, treap, splay tree and so on. We do not often think of B-tree, as B-tree is commonly introduced as an on-disk data structure rather than in-memory one. Is B-tree also a good data structure for in-memory ordered dictionary? I used to search for the performance comparison between B-tree and binary search trees, but ended up with nothing useful. It seems that only I am interested in such comparison and so I have to do it by myself.</p>
<p>I found John-Mark Gurney’s <a href="http://resnet.uoregon.edu/~gurney_j/jmpc/btree.html">B-tree</a> via google search. It is well coded and full of clever ideas. The original version has small memory footprint, but it is not as fast as STL&#8217;s red-black tree. I studied this source codes and think I should be able to further optimize it. In the end, I got my kbtree.h macro library. As you can see in my hash table benchmark, the modified version beats STL set while using even smaller memory than the original version. I think I am now at the position to say: at least for some applications, B-tree is a better ordered data structure than most of binary search trees.</p>
<p>The most attractive feature of B-tree is its small memory usage. A binary tree needs at least two pointers for each record, which amounts to 16N on a modern 64-bit systems. A B-tree only needs one pointer. Although in a B-tree each node may not be full, a sufficiently large B-tree should be at least 50% full by definition and in average around 75% full. On a 64-bit system, the extra memory is only 8N/0.75+KN(1/0.75-1)=(10+0.3K)N, where K is the size of a key. In fact we can do even better as we do not need to allocate the null pointers in leaves. The practical memory overhead can be reduced to below (5+0.3K)N (in fact, as the majority of nodes in a B-tree are leaves, the factor 5 should be smaller in practice), far better than a binary search tree. On speed, no binary search tree with just two additional pointers (splay tree and hash treap) can achieve the best performance. We usually need additional information at each node (AVL tree and standard red-black tree) or a random number (treap) to get good performance. B-tree is different. It is even faster than the standard red-black tree while still using (5+0.3K)N extra memory! People should definitely pay more attention to B-tree.</p>
<p><strong>Update:</strong> The modified B-tree is available <a href="http://www.freewebs.com/attractivechaos/kbtree.h">here</a> (<a href="http://www.freewebs.com/attractivechaos/kbtree.h.html">HTML</a>) as a single C header file. Example is <a href="http://www.freewebs.com/attractivechaos/kbtest.c">here</a>. Currently, the APIs are not very friendly but are ready to use. In case you want to give a try. Note that you must make sure the key is absent in the tree before kb_put() and make sure the key is present in the tree before calling kb_del().</p>
<p>Someone has corrected me. STL is a specification, not an implementation. By STL in my blog, I always mean SGI STL, the default STL that comes with GCC.</p>
<p>Over the weekend I have done a more complete benchmark of various libraries on search trees and hash tables. Please read <a href="http://attractivechaos.wordpress.com/2008/09/28/futher-discussion-on-search-trees/">this post</a> if you are interested.</p>
<p>I realize that a lot of red-black tree implementations do not need a parent pointer, although SGI STL&#8217;s one uses. My comment below is somewhat wrong.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/attractivechaos.wordpress.com/507/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/attractivechaos.wordpress.com/507/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/attractivechaos.wordpress.com/507/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/attractivechaos.wordpress.com/507/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/attractivechaos.wordpress.com/507/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/attractivechaos.wordpress.com/507/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/attractivechaos.wordpress.com/507/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/attractivechaos.wordpress.com/507/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/attractivechaos.wordpress.com/507/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/attractivechaos.wordpress.com/507/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=507&subd=attractivechaos&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://attractivechaos.wordpress.com/2008/09/24/b-tree-vs-binary-search-tree/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/047ebc7bb9ff37a0da844413856e92cb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">attractivechaos</media:title>
		</media:content>
	</item>
		<item>
		<title>A Simple Generic Vector Container in C</title>
		<link>http://attractivechaos.wordpress.com/2008/09/22/a-simple-vector-macro-library-in-c/</link>
		<comments>http://attractivechaos.wordpress.com/2008/09/22/a-simple-vector-macro-library-in-c/#comments</comments>
		<pubDate>Mon, 22 Sep 2008 08:28:10 +0000</pubDate>
		<dc:creator>attractivechaos</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[macro]]></category>
		<category><![CDATA[myprog]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://attractivechaos.wordpress.com/?p=484</guid>
		<description><![CDATA[I do not see much need to have a vector container in C as a vector is simply an array and array operations are all very simple. Nontheless, it might still better to implement one, for the sake of completeness. Here is the code. The library is almost as fast as the fastest code you [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=484&subd=attractivechaos&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I do not see much need to have a vector container in C as a vector is simply an array and array operations are all very simple. Nontheless, it might still better to implement one, for the sake of completeness. Here is the code. The library is almost as fast as the fastest code you can write in C.</p>
<pre class="brush: cpp;">
#ifndef AC_KVEC_H
#define AC_KVEC_H

#include &lt;stdint.h&gt;
#include &lt;stdlib.h&gt;

#define kv_roundup32(x) (--(x), (x)|=(x)&gt;&gt;1, (x)|=(x)&gt;&gt;2, (x)|=(x)&gt;&gt;4, (x)|=(x)&gt;&gt;8, (x)|=(x)&gt;&gt;16, ++(x))

#define kvec_t(type) struct { uint32_t n, m; type *a; }
#define kv_init(v) ((v).n = (v).m = 0, (v).a = 0)
#define kv_destroy(v) free((v).a)
#define kv_A(v, i) ((v).a[(i)])
#define kv_pop(v) ((v).a[--(v).n])
#define kv_size(v) ((v).n)
#define kv_max(v) ((v).m)

#define kv_resize(type, v, s)  ((v).m = (s), (v).a = (type*)realloc((v).a, sizeof(type) * (v).m))

#define kv_push(type, v, x) do {									\
		if ((v).n == (v).m) {										\
			(v).m = (v).m? (v).m&lt;&lt;1 : 2;							\
			(v).a = (type*)realloc((v).a, sizeof(type) * (v).m);	\
		}															\
		(v).a[(v).n++] = (x);										\
	} while (0)

#define kv_pushp(type, v) (((v).n == (v).m)?							\
						   ((v).m = ((v).m? (v).m&lt;&lt;1 : 2),				\
							(v).a = (type*)realloc((v).a, sizeof(type) * (v).m), 0)	\
						   : 0), ((v).a + ((v).n++))

#define kv_a(type, v, i) ((v).m &lt;= (i)?									\
						  ((v).m = (v).n = (i) + 1, kv_roundup32((v).m), \
						   (v).a = (type*)realloc((v).a, sizeof(type) * (v).m), 0) \
						  : (v).n &lt;= (i)? (v).n = (i)					\
						  : 0), (v).a[(i)]
#endif
</pre>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/attractivechaos.wordpress.com/484/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/attractivechaos.wordpress.com/484/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/attractivechaos.wordpress.com/484/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/attractivechaos.wordpress.com/484/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/attractivechaos.wordpress.com/484/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/attractivechaos.wordpress.com/484/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/attractivechaos.wordpress.com/484/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/attractivechaos.wordpress.com/484/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/attractivechaos.wordpress.com/484/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/attractivechaos.wordpress.com/484/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=484&subd=attractivechaos&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://attractivechaos.wordpress.com/2008/09/22/a-simple-vector-macro-library-in-c/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/047ebc7bb9ff37a0da844413856e92cb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">attractivechaos</media:title>
		</media:content>
	</item>
		<item>
		<title>Thoughts on Generic Programming in C</title>
		<link>http://attractivechaos.wordpress.com/2008/09/21/thoughts-on-generic-programming-in-c/</link>
		<comments>http://attractivechaos.wordpress.com/2008/09/21/thoughts-on-generic-programming-in-c/#comments</comments>
		<pubDate>Sun, 21 Sep 2008 16:10:36 +0000</pubDate>
		<dc:creator>attractivechaos</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[cpp]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[thinking]]></category>

		<guid isPermaLink="false">http://attractivechaos.wordpress.com/?p=479</guid>
		<description><![CDATA[I came across two interviews (here and here) of Alexander Stepanov, the father of STL. There are quite a lot of interesting bits. For example, he thinks C++ is the best programming language to realize his goal, but he is also strongly against OOP at the same time. In addition, he has paid a lot [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=479&subd=attractivechaos&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I came across two interviews (<a href="http://www.stlport.org/resources/StepanovUSA.html">here</a> and <a href="http://www.stepanovpapers.com/drdobbs-interview.html">here</a>) of <a href="http://en.wikipedia.org/wiki/Alexander_Stepanov">Alexander Stepanov</a>, the father of STL. There are quite a lot of interesting bits. For example, he thinks C++ is the best programming language to realize his goal, but he is also strongly against OOP at the same time. In addition, he has paid a lot of efforts on efficiency, which we can see from STL. He said: &#8220;It is silly to abstract an algorithm in such a way that when you instantiate it back it becomes inefficient&#8221;. I like these two interviews because I think in the same way. The only exception is I do not use STL, although I think it is the best generic library and I like it a lot. But why?</p>
<p>Two reasons. Firstly, STL is written in C++, which makes it unavailable to all C projects. It is possible to only use STL and forget all the other features in C++, but people rarely do so. At least I have not seen such a project where STL is combined with procedural programming. In addition, C++ projects are usually less portable than C projects and STL makes it worse. It puts a lot of stress on C++ compilers. Even Stepanov agreeed, by the time of the interview, that &#8220;The unfortunate reality is that a lot of code in the present implementation of STL is suboptimal because of the compiler limitations and bugs of the compilers I had to use when I was developing STL&#8221;. Secondly, using STL also means much longer compiling time. I remembered I used to compile a customized Linux kernel for my old laptop in an hour. Probably I would spend more than a day to compile if it was written using C++/STL.</p>
<p>A generic container library would benefit a lot of C programmers, but so far I am not aware of any efficient implementation. Glib tries to achieve so, but it uses void* and this inevitably will incur overhead and complicate interfaces. And finally, I decide to write my own one. Ideally (but probably impractically) I want to achieve four goals: a) efficiency in speed and space; b) elegance in interface; c) independency between functinality and d) simplicity in codes. However, currently I am not competent enough to achieve all these goals and I am not a professional programmer at all (and so cannot invest enough time). As I said in my About page, I mainly do this to please myself.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/attractivechaos.wordpress.com/479/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/attractivechaos.wordpress.com/479/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/attractivechaos.wordpress.com/479/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/attractivechaos.wordpress.com/479/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/attractivechaos.wordpress.com/479/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/attractivechaos.wordpress.com/479/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/attractivechaos.wordpress.com/479/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/attractivechaos.wordpress.com/479/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/attractivechaos.wordpress.com/479/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/attractivechaos.wordpress.com/479/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=479&subd=attractivechaos&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://attractivechaos.wordpress.com/2008/09/21/thoughts-on-generic-programming-in-c/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/047ebc7bb9ff37a0da844413856e92cb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">attractivechaos</media:title>
		</media:content>
	</item>
		<item>
		<title>Calculating Median</title>
		<link>http://attractivechaos.wordpress.com/2008/09/13/calculating-median/</link>
		<comments>http://attractivechaos.wordpress.com/2008/09/13/calculating-median/#comments</comments>
		<pubDate>Sat, 13 Sep 2008 19:26:20 +0000</pubDate>
		<dc:creator>attractivechaos</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[myprog]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://attractivechaos.wordpress.com/?p=440</guid>
		<description><![CDATA[Here is an example that google does not give me the result in the first page. I want to know how to calculate median efficiently, and so I search &#8220;c calculate median&#8221;. In the first result page, google brings me to several forums which only show very naive implementations. The 11th result, this page, is [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=440&subd=attractivechaos&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Here is an example that google does not give me the result in the first page. I want to know how to calculate median efficiently, and so I search &#8220;c calculate median&#8221;. In the first result page, google brings me to several forums which only show very naive implementations. The 11th result, <a href="http://ndevilla.free.fr/median/index.html">this page</a>, is the truely invaluable one which should be favoured by most programmers. I do not want to replicate that website. I just want to show you a function that is adapted from <a href="http://ndevilla.free.fr/median/median/src/quickselect.c">quickselect.c</a> on the website. This function calculates the k-smallest (0&lt;=k&lt;n) element in an array. Its time complexity is linear to the size of the array and in practice it runs much faster than sorting and then locating the k-smallest element.</p>
<pre class="brush: cpp;">
type_t ks_ksmall(size_t n, type_t arr[], size_t kk)
{
	type_t *low, *high, *k, *ll, *hh, *middle;
	low = arr; high = arr + n - 1; k = arr + kk;
	for (;;) {
		if (high &lt;= low) return *k;
		if (high == low + 1) {
			if (cmp(*high, *low)) swap(type_t, *low, *high);
			return *k;
		}
		middle = low + (high - low) / 2;
		if (lt(*high, *middle)) swap(type_t, *middle, *high);
		if (lt(*high, *low)) swap(type_t, *low, *high);
		if (lt(*low, *middle)) swap(type_t, *middle, *low);
		swap(type_t, *middle, *(low+1)) ;
		ll = low + 1; hh = high;
		for (;;) {
			do ++ll; while (lt(*ll, *low));
			do --hh; while (lt(*low, *hh));
			if (hh &lt; ll) break;
			swap(type_t, *ll, *hh);
		}
		swap(type_t, *low, *hh);
		if (hh &lt;= k) low = ll;
		if (hh &gt;= k) high = hh - 1;
	}
}
</pre>
<p>In this funcion, type_t is a type, swap() swaps two values, and lt() is a macro or a function that returns true if and only if the first value is smaller.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/attractivechaos.wordpress.com/440/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/attractivechaos.wordpress.com/440/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/attractivechaos.wordpress.com/440/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/attractivechaos.wordpress.com/440/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/attractivechaos.wordpress.com/440/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/attractivechaos.wordpress.com/440/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/attractivechaos.wordpress.com/440/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/attractivechaos.wordpress.com/440/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/attractivechaos.wordpress.com/440/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/attractivechaos.wordpress.com/440/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/attractivechaos.wordpress.com/440/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/attractivechaos.wordpress.com/440/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=440&subd=attractivechaos&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://attractivechaos.wordpress.com/2008/09/13/calculating-median/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/047ebc7bb9ff37a0da844413856e92cb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">attractivechaos</media:title>
		</media:content>
	</item>
		<item>
		<title>The Google Dense Hashtable Library</title>
		<link>http://attractivechaos.wordpress.com/2008/09/12/the-google-hash-table-library/</link>
		<comments>http://attractivechaos.wordpress.com/2008/09/12/the-google-hash-table-library/#comments</comments>
		<pubDate>Fri, 12 Sep 2008 09:52:21 +0000</pubDate>
		<dc:creator>attractivechaos</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[hash]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://attractivechaos.wordpress.com/?p=426</guid>
		<description><![CDATA[Google dense hash table (google-dense) implements an open addressing hash table with quardric probing. It requires users to set an empty element and a deleted element which are distinct from all the other valid keys in the hash table. Google-dense tests whether a bucket is empty or deleted by performing key comparisons. It is fast [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=426&subd=attractivechaos&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Google dense hash table (google-dense) implements an open addressing hash table with quardric probing. It requires users to set an empty element and a deleted element which are distinct from all the other valid keys in the hash table. Google-dense tests whether a bucket is empty or deleted by performing key comparisons. It is fast for integer keys where comparisons are cheap but will have overhead for string keys. In contrast, khash uses a bit vector to record which bucket is empty or deleted. On string keys, it avoids overhead for additional string comparisons, but will incur a potential cache miss when it is checking the bit vector. It seems that this cache miss costs a little less than one or two string comparisons. As a consequence, google dense hash is more efficient for simple keys and khash is more efficient for complex keys. This is what we see from <a href="http://attractivechaos.wordpress.com/2008/08/28/comparison-of-hash-table-libraries/">my hash table benchmark</a>.</p>
<p>Another difference between google-map (plus almost all the other hash map implementations I am aware of) and khash-map is that google-map keeps key-value pair in one array while khash-map keeps keys and values in two separate arrays. Keeping one array helps cache efficiency because we will not incur a cache miss when we have located the bucket via a key. However, putting a key and a value in one struct/class will waste memory when the key type and the value type are not aligned. For example, on 64-bit systems, if the key type is &#8220;const char*&#8221; and the value type is &#8220;int&#8221;, 25% of memory is wasted on memory alignment. Keeping two separate arrays like khash will not have this problem, but this strategy will cost one additional cache miss when we retrieve a value. Khash was initially designed for a huge hash table with 64-bit integers as keys and 8-bit integers as values. 44% of memory would be wasted on memory alignment if I put key-value pair in a struct. This was unacceptable for that application. Whether to separate keys and values is a tradeoff between memory and speed.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/attractivechaos.wordpress.com/426/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/attractivechaos.wordpress.com/426/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/attractivechaos.wordpress.com/426/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/attractivechaos.wordpress.com/426/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/attractivechaos.wordpress.com/426/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/attractivechaos.wordpress.com/426/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/attractivechaos.wordpress.com/426/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/attractivechaos.wordpress.com/426/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/attractivechaos.wordpress.com/426/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/attractivechaos.wordpress.com/426/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/attractivechaos.wordpress.com/426/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/attractivechaos.wordpress.com/426/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=426&subd=attractivechaos&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://attractivechaos.wordpress.com/2008/09/12/the-google-hash-table-library/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/047ebc7bb9ff37a0da844413856e92cb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">attractivechaos</media:title>
		</media:content>
	</item>
		<item>
		<title>Implementing Generic Hash Library in C</title>
		<link>http://attractivechaos.wordpress.com/2008/09/02/implementing-generic-hash-library-in-c/</link>
		<comments>http://attractivechaos.wordpress.com/2008/09/02/implementing-generic-hash-library-in-c/#comments</comments>
		<pubDate>Tue, 02 Sep 2008 20:18:32 +0000</pubDate>
		<dc:creator>attractivechaos</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[hash]]></category>
		<category><![CDATA[myprog]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://attractivechaos.wordpress.com/?p=358</guid>
		<description><![CDATA[Synopsis
Here is an simple example showing how to use khash.h library:

#include &#34;khash.h&#34;
KHASH_MAP_INIT_INT(32, char)
int main() {
	int ret, is_missing;
	khiter_t k;
	khash_t(32) *h = kh_init(32);
	k = kh_put(32, h, 5, &#38;ret);
	if (!ret) kh_del(32, h, k);
	kh_value(h, k) = 10;
	k = kh_get(32, h, 10);
	is_missing = (k == kh_end(h));
	k = kh_get(32, h, 5);
	kh_del(32, h, k);
	for (k = kh_begin(h); k != kh_end(h); ++k)
		if (kh_exist(h, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=358&subd=attractivechaos&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><strong>Synopsis</strong></p>
<p>Here is an simple example showing how to use <a href="http://www.freewebs.com/attractivechaos/khash.h.html">khash.h</a> library:</p>
<pre class="brush: cpp;">
#include &quot;khash.h&quot;
KHASH_MAP_INIT_INT(32, char)
int main() {
	int ret, is_missing;
	khiter_t k;
	khash_t(32) *h = kh_init(32);
	k = kh_put(32, h, 5, &amp;ret);
	if (!ret) kh_del(32, h, k);
	kh_value(h, k) = 10;
	k = kh_get(32, h, 10);
	is_missing = (k == kh_end(h));
	k = kh_get(32, h, 5);
	kh_del(32, h, k);
	for (k = kh_begin(h); k != kh_end(h); ++k)
		if (kh_exist(h, k)) kh_value(h, k) = 1;
	kh_destroy(32, h);
	return 0;
}
</pre>
<p>The second line says we want to use a hash map with int as key and char as value. khash_t(int) is a type. kh_get() and kh_put() returns an iterator, or the position in the hash table. kh_del() erases the key-value in the bucket pointed by the iterator. kh_begin() and kh_end() return the begin and the end of iterator, respectively. And kh_exist() tests whether the bucket at the iterator is filled with a key-value. The APIs are not so concise in comparison to C++ template, but are very straightforward and flexible. How can this be done?</p>
<p><strong>Achieving generic programming in C</strong></p>
<p>The core part of khash.h is:</p>
<pre class="brush: cpp;">#define KH_INIT(name, key_t, val_t, is_map, _hashf, _hasheq) \
  typedef struct { \
    int n_buckets, size, n_occupied, upper_bound; \
    unsigned *flags; \
    key_t *keys; \
    val_t *vals; \
  } kh_##name##_t; \
  static inline kh_##name##_t *init_##name() { \
    return (kh_##name##_t*)calloc(1, sizeof(kh_##name##_t)); \
  } \
  static inline int get_##name(kh_##name##_t *h, key_t k) \
  ... \
  static inline void destroy_##name(kh_##name##_t *h) { \
    if (h) { \
      free(h-&gt;keys); free(h-&gt;flags); free(h-&gt;vals); free(h); \
    } \
  }

#define _int_hf(key) (unsigned)(key)
#define _int_heq(a, b) (a == b)
#define khash_t(name) kh_##name##_t
#define kh_init(name) init_##name()
#define kh_get(name, h, k) get_##name(h, k)
#define kh_destroy(name, h) destroy_##name(h)
...
#define KHASH_MAP_INIT_INT(name, val_t) \
	KH_INIT(name, unsigned, val_t, is_map, _int_hf, _int_heq)
</pre>
<p>In macro &#8216;KH_INIT&#8217;, name is a unique symbol that distinguishes hash tables of different types, key_t the type of key, val_t the type of value, is_map is 0 or 1 indicating whether to allocate memory for vals, _hashf is a hash function/macro and _hasheq the comparison function/macro. Macro &#8216;KHASH_MAP_INIT_INT&#8217; is a convenient interface to hash with integer keys.</p>
<p>When &#8216;KHASH_MAP_INIT_INT(32, char)&#8217; is used in a C source code file the following codes will be inserted:</p>
<pre class="brush: cpp;">
  typedef struct {
    int n_buckets, size, n_occupied, upper_bound;
    unsigned *flags;
    unsigned *keys;
    char *vals;
  } kh_int_t;
  static inline kh_int_t *init_int() {
    return (kh_int_t*)calloc(1, sizeof(kh_int_t));
  }
  static inline int get_int(kh_int_t *h, unsigned k)
  ...
  static inline void destroy_int(kh_int_t *h) {
    if (h) {
      free(h-&gt;keys); free(h-&gt;flags); free(h-&gt;vals); free(h);
    }
  }
</pre>
<p>And when we call: &#8216;kh_get(int, h, 5)&#8217;, we are calling &#8216;get_int(h, 5)&#8217; which is defined by calling KH_INIT(int) macro. In this way, we can effectively achieve generic programming with simple interfaces. As we use inline and macros throughout, the efficiency is not affected at all. In <a href="http://attractivechaos.wordpress.com/2008/08/28/comparison-of-hash-table-libraries/">my hash table benchmark</a>, it is as fast and light-weighted as the C++ implementation.</p>
<p><strong>Other technical concerns</strong></p>
<ul>
<li><strong>Solving collisions</strong>. I have discussed this in my previous post. I more like to achieve smaller memory and therefore I choose open addressing.</li>
<li><strong>Grouping key-value pairs or not</strong>. In the current implementation, keys and values are kept in separated arrays. This strategy will cause additional cache misses when keys and values are retrieved twice. Grouping key-value in a struct is more cache efficient. However, the good side of separating keys and values is this avoids waste of memory when key type and value type cannot be aligned well (e.g. key is an integer while value is a character). I would rather trade speed a bit for smaller memory. In addition, it is not hard to use a struct has a key in the current framework.</li>
<li><strong>Space efficient rehashing</strong>. Traditional rehashing requires to allocate one addition hash and move elements in the old hash to the new one. For most hash implementations, this means we need 50% extra working space to enlarge a hash. This is not necessary. In khash.h, only a new flags array is allocated on rehashing. Array keys and values are enlarged with realloc which does not claim more memory than the new hash. Keys and values are move from old positions to new positions in the same memory space. This strategy also helps to clear all buckets marked as deleted without changing the size of a hash.</li>
</ul>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/attractivechaos.wordpress.com/358/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/attractivechaos.wordpress.com/358/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/attractivechaos.wordpress.com/358/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/attractivechaos.wordpress.com/358/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/attractivechaos.wordpress.com/358/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/attractivechaos.wordpress.com/358/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/attractivechaos.wordpress.com/358/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/attractivechaos.wordpress.com/358/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/attractivechaos.wordpress.com/358/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/attractivechaos.wordpress.com/358/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/attractivechaos.wordpress.com/358/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/attractivechaos.wordpress.com/358/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=358&subd=attractivechaos&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://attractivechaos.wordpress.com/2008/09/02/implementing-generic-hash-library-in-c/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/047ebc7bb9ff37a0da844413856e92cb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">attractivechaos</media:title>
		</media:content>
	</item>
		<item>
		<title>Generic Programming in C</title>
		<link>http://attractivechaos.wordpress.com/2008/09/02/generic-programming-in-c/</link>
		<comments>http://attractivechaos.wordpress.com/2008/09/02/generic-programming-in-c/#comments</comments>
		<pubDate>Tue, 02 Sep 2008 17:31:33 +0000</pubDate>
		<dc:creator>attractivechaos</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://attractivechaos.wordpress.com/?p=345</guid>
		<description><![CDATA[Template in C++ is the single reason that I still keep using it. Previously, I thought generic programming in C is nothing but ugly and painful. Now I have changed my mind a bit, in the light of tree.h written by Niels Provos. Generic programming in C can be done without much pain and with [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=345&subd=attractivechaos&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Template in C++ is the single reason that I still keep using it. Previously, I thought <a href="http://en.wikipedia.org/wiki/Generic_programming">generic programming</a> in C is nothing but ugly and painful. Now I have changed my mind a bit, in the light of <a href="http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/sys/tree.h">tree.h</a> written by <a href="http://www.citi.umich.edu/u/provos/">Niels Provos</a>. Generic programming in C can be done without much pain and with just slightly less elegance in comparison to C++ implementations. How can this be done? Macros, of course. But in what form macros are used is where all the tricks come in.</p>
<p>The first way to achieve generic programming is to pass a type to macros. <a href="http://people.freebsd.org/~jasone/">Jason Evans</a>&#8216; <a href="http://people.freebsd.org/~jasone/jemalloc/progs/rb.h">rb.h</a> is an example. Each operation on an RB tree is a macro. Users have to provide the type of the data in the tree and a comparison function with each macro. It is not hard to think of this way, but we can do better.</p>
<p>In <a href="http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/sys/tree.h?rev=1.6.2.1;content-type=text%2Fplain">tree.h</a>, Niels gives a better solution: to use token concatenation. The key macro is SPLAY_PROTOTYPE(name, type, field, cmp). It is a huge macro that defines several operations, in the form of &#8220;static inline&#8221; functions, on the splay tree. These functions will be inserted to the C source code which uses the macro. Using SPLAY_PROTOTYPE() with different &#8220;name&#8221;s will insert different functions. For example, when &#8220;SPLAY_PROTOTYPE(int32, int, data, intcmp)&#8221; is invoked, the insertion function will be &#8220;int32_SPLAY_INSERT()&#8221;. Splay trees with different &#8220;name&#8221;s can coexist in one C source code because their operations have different names. At the end of tree.h, Niels further defines &#8220;#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)&#8221;. Then In the C source code, we can call insertion with &#8220;RB_INSERT(int32, x, y)&#8221;. In comparison to a C++ template implementation, the only line you need to add is SPLAY_PROTOTYPE(). Calling operations is as easy.</p>
<p>I will further explain this idea when I present my khash implementation in C.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/attractivechaos.wordpress.com/345/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/attractivechaos.wordpress.com/345/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/attractivechaos.wordpress.com/345/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/attractivechaos.wordpress.com/345/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/attractivechaos.wordpress.com/345/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/attractivechaos.wordpress.com/345/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/attractivechaos.wordpress.com/345/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/attractivechaos.wordpress.com/345/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/attractivechaos.wordpress.com/345/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/attractivechaos.wordpress.com/345/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/attractivechaos.wordpress.com/345/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/attractivechaos.wordpress.com/345/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=345&subd=attractivechaos&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://attractivechaos.wordpress.com/2008/09/02/generic-programming-in-c/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/047ebc7bb9ff37a0da844413856e92cb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">attractivechaos</media:title>
		</media:content>
	</item>
		<item>
		<title>Comparison of Hash Table Libraries</title>
		<link>http://attractivechaos.wordpress.com/2008/08/28/comparison-of-hash-table-libraries/</link>
		<comments>http://attractivechaos.wordpress.com/2008/08/28/comparison-of-hash-table-libraries/#comments</comments>
		<pubDate>Thu, 28 Aug 2008 22:22:54 +0000</pubDate>
		<dc:creator>attractivechaos</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[benchmark]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[cpp]]></category>
		<category><![CDATA[hash]]></category>
		<category><![CDATA[myprog]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://attractivechaos.wordpress.com/?p=278</guid>
		<description><![CDATA[As a Perl programmer, I enjoy a lot using hash tables. I keep this habit in C/C++ programming. Then what C/C++ hash libraries are available? How are they compared to each other? In this post, I will give a brief review of hash libraries and present a small benchmark showing their practical performance.
Hash table libraries
In [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=278&subd=attractivechaos&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>As a Perl programmer, I enjoy a lot using hash tables. I keep this habit in C/C++ programming. Then what C/C++ hash libraries are available? How are they compared to each other? In this post, I will give a brief review of hash libraries and present a small benchmark showing their practical performance.</p>
<p><strong>Hash table libraries</strong></p>
<p>In C++, the most widely used hash table implementation is hash_map/set in <a href="http://www.sgi.com/tech/stl/">SGI STL</a>, which is part of the GCC compiler. Note that hash_map/set is SGI&#8217;s extention to STL, but is not part of STL. TR1 (<a href="http://en.wikipedia.org/wiki/Technical_Report_1">technical report 1</a>) tries to standardize hash tables. It provides unordered_map/set with similar API to hash_map/set. Most of TR1 routines are available since gcc-4.0. <a href="http://code.google.com/p/google-sparsehash/">Google sparse hash</a> is another C++ hash table template library with similar API to hash_map/set. It provides two implementations, one is efficient in speed and the other is in memory.</p>
<p>In contrast, there are few good C libraries around. I have tried <a href="http://www.sunrisetel.net/software/devtools/sunrise-data-dictionary.shtml">SunriseDD</a>, <a href="http://uthash.sourceforge.net/">uthash</a>, <a href="http://linux.die.net/man/3/hsearch">glibc hash table</a>, <a href="http://freshmeat.net/projects/hashit/">hashit</a>, Christopher Clark&#8217;s <a href="http://www.cl.cam.ac.uk/~cwc22/hashtable/">hashtable</a>, <a href="http://www.gtk.org/">glib hash table</a> and <a href="http://www.ipd.bth.se/ska/sim_home/libghthash.html">ghthash</a>. SunriseDD sounds a great library that implements a lock-free hash table. However, I am not sure how to install it or use it, although the code itself is well documented. Uthash is a single header file. It is quite complex to use and incompatiable with C++. It also lacks basic APIs such as counting how many elements in the hash table. Glibc hash and hashit seem to only implement static hash tables. Glibc hash even does not have deletion operation. Only glib hash, CC&#8217;s hashtable and ghthash implement most of common operations. And they still have their weakness in comparison to C++ implementations (see below).</p>
<p><strong>D</strong><strong>esign of the benchmark</strong></p>
<p>The benchmark is comprised of two experiments. In the first experiment, a random integer array of 5 million elements is generated with about 1.25 million distinct keys. Each element is then tested whether it is present in the hash. If the element is in the hash, it will be removed; otherwise, it will be inserted. 625,792 distinct keys will be in the hash after this process. To test performance on string input, I convert integers to strings with sprintf().</p>
<p>The second experiment is designed by Craig Silverstein, the author of sparsehash. I am using his source codes. This experiment tests the performance of insertion from zero sized hash, insertion from preallocated hash, replacement, query, query of empty hash, and removal.</p>
<p><strong>Results</strong></p>
<p>The following table gives the results in the first experiment:</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="90">Library</td>
<td>Mac-intCPU (sec)</td>
<td>Mac-strCPU (sec)</td>
<td>Mac PeakMem (MB)</td>
<td>Linux-intCPU (sec)</td>
<td>Linux-strCPU (sec)</td>
<td>Linux PeakMem (MB)</td>
</tr>
<tr>
<td>glib</td>
<td>1.904</td>
<td>2.436</td>
<td>11.192</td>
<td>3.490</td>
<td>4.720</td>
<td>24.968</td>
</tr>
<tr>
<td>ghthash</td>
<td>2.593</td>
<td>2.869</td>
<td>29.0/39.0</td>
<td>3.260</td>
<td>3.460</td>
<td>61.232</td>
</tr>
<tr>
<td>CC&#8217;s hashtable</td>
<td>2.740</td>
<td>3.424</td>
<td>59.756</td>
<td>3.040</td>
<td>4.050</td>
<td>129.020</td>
</tr>
<tr>
<td>TR1</td>
<td>1.371</td>
<td>2.571</td>
<td>16.140</td>
<td>1.750</td>
<td>3.300</td>
<td>28.648</td>
</tr>
<tr>
<td>STL hash_set</td>
<td>1.631</td>
<td>2.698</td>
<td>14.592</td>
<td>2.070</td>
<td>3.430</td>
<td>25.764</td>
</tr>
<tr>
<td>google-sparse</td>
<td>2.957</td>
<td>6.098</td>
<td>4.800</td>
<td>2.560</td>
<td>6.930</td>
<td>5.42/8.54</td>
</tr>
<tr>
<td>google-dense</td>
<td>0.700</td>
<td>2.833</td>
<td>24.616</td>
<td>0.550</td>
<td>2.820</td>
<td>24.7/49.3</td>
</tr>
<tr>
<td>khash (C++)</td>
<td>1.089</td>
<td>2.372</td>
<td>6.772</td>
<td>1.100</td>
<td>2.900</td>
<td>6.88/13.1</td>
</tr>
<tr>
<td>khash (C)</td>
<td>0.987</td>
<td>2.294</td>
<td>6.780</td>
<td>1.140</td>
<td>2.940</td>
<td>6.91/13.1</td>
</tr>
<tr>
<td>STL set (RB)</td>
<td>5.898</td>
<td>12.978</td>
<td>19.868</td>
<td>7.840</td>
<td>18.620</td>
<td>29.388</td>
</tr>
<tr>
<td>kbtree (C)</td>
<td>3.080</td>
<td>13.413</td>
<td>3.268</td>
<td>4.260</td>
<td>17.620</td>
<td>4.86/9.59</td>
</tr>
<tr>
<td>NP&#8217;s splaytree</td>
<td>8.455</td>
<td>23.369</td>
<td>8.936</td>
<td>11.180</td>
<td>27.610</td>
<td>19.024</td>
</tr>
</tbody>
</table>
<p>Notes:</p>
<ul>
<li>Please be aware that changing the size of input data may change the ranking of speed and memory. The speed of a library may vary up to 10% in two different runs.</li>
<li>CPU time is measured in seconds. Memory denotes the peak memory, measured in MB.</li>
<li>For string hash, only the pointer to a string is inserted. Memory in the table does not count the space used by strings.</li>
<li>If two numbers are given for memory, the first is for integer keys and the second for string keys.</li>
<li>For all C++ libraries and khash.h, one operation is needed to achieve &#8220;insert if absent; delete otherwise&#8221;. Glib and ghthash require two operations, which does not favour these two libraries.</li>
<li>The speed may also be influenced by the efficiency of hash funtions. Khash and Glib use the same hash function. TR1/SGI-STL/google-hash use another hash function. Fortunately, to my experiment, the two string hash functions have quite similar performance and so the benchmark reflects the performance of the overall hash libraries instead of just hash functions.</li>
<li>For glib and ghthash, what is inserted is the pointer to the integer instead of the integer itself.</li>
<li>Ghthash supports dynamic hash table. However, the results do not seem correct when this is switched on. I am using fixed-size hash table. This favours ghthash.</li>
<li>CC&#8217;s hashtable will force to free a key, which is not implemented in all the other libraries. This behaviour will add overhead on both speed and memory in my benchmark (but probably not in other applications). The memory is measured for integer keys.</li>
<li>This simple benchmark does not test the strength and weakness of splay tree.</li>
</ul>
<p>And here is the result of the second experiment:</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>Library</td>
<td>grow</td>
<td>pred/grow</td>
<td>replace</td>
<td>fetch</td>
<td>fetchnull</td>
<td>remove</td>
<td>Memory</td>
</tr>
<tr>
<td>TR1</td>
<td>194.2</td>
<td>183.9</td>
<td>30.7</td>
<td>15.6</td>
<td>15.2</td>
<td>83.4</td>
<td>224.6</td>
</tr>
<tr>
<td>STL hash_map</td>
<td>149.0</td>
<td>110.5</td>
<td>35.6</td>
<td>11.5</td>
<td>14.0</td>
<td>87.2</td>
<td>204.2</td>
</tr>
<tr>
<td>STL map</td>
<td>289.9</td>
<td>289.9</td>
<td>141.3</td>
<td>134.3</td>
<td>7.0</td>
<td>288.6</td>
<td>236.8</td>
</tr>
<tr>
<td>google-sparse</td>
<td>417.2</td>
<td>237.6</td>
<td>89.5</td>
<td>84.0</td>
<td>12.1</td>
<td>100.4</td>
<td>85.4</td>
</tr>
<tr>
<td>google-dense</td>
<td>108.4</td>
<td>39.4</td>
<td>17.8</td>
<td>8.3</td>
<td>2.8</td>
<td>18.0</td>
<td>256.0</td>
</tr>
<tr>
<td>khash (C++)</td>
<td>111.2</td>
<td>99.2</td>
<td>26.1</td>
<td>11.5</td>
<td>3.0</td>
<td>17.4</td>
<td>198.0</td>
</tr>
</tbody>
</table>
<p>Notes:</p>
<ul>
<li>CPU time is measured in nanosecond for each operation. Memory is measured by TCmalloc. It is the memory difference before and after the allocation of the hash table, instead of the peak memory.</li>
<li>In this experiment, integers are inserted in order and there are no collisions in the hash table.</li>
<li>All these libraries provide similar API.</li>
</ul>
<p><strong>Discussions</strong></p>
<ul>
<li><strong>Speed and memory.</strong> The larger the hash table, the fewer collisions may occur and the faster the speed. For the same hash library, increasing memory always increases speed. When we compare two libraries, both speed and memory should be considered.</li>
<li><strong>C vs. C++.</strong> All C++ implementations have similar API. It is also very easy to use for any type of keys. Both C libraries, ghthash and glib, can only keep pointers to the keys, which complicates API and increases memory especially for 64-bit systems where a pointer takes 8 bytes. In general, C++ libraries is perferred over C ones. Surprisingly, on 32-bit Mac OS X, glib outperforms TR1 and STL for string input. This might indicate that the glib implementation itself is very efficient, but just the lack of functionality in C affects the performance.</li>
<li><strong>Generic programming in C</strong>. Except my khash.h, all the other C hash libraries use (void*) to achieve generic typing. Using void* is okey for strings, but will cause overhead for integers. This is why all C libraries, except khash.h, is slower than C++ libraries on integer keys, but close to on string keys.</li>
<li><strong>Open addressing vs. chaining hash.</strong> Khash and google hash implement open addressing hash while the remaining implement chaining hash. In open addressing hash, the size of each bucket equals the size of a key plus 0.25 byte. Google sparsehash further compresses unused bucket to 1 bit, achieving high memory efficiency. In chaining hash, the memory overhead of each bucket is at least 4 bytes on 32bit machines, or 8 bytes on 64bit machines. However, chaining hash is less affected when the hash table is nearly full. In practice, both open addressing and chaining hash occupy similar memory under similar speed. Khash takes less peak memory mainly due to its advanced technique in rehashing which reduces memory usage. So far as speed is concerned, chaining hash may have fewer comparison between keys. We can see this from the fact that the speed of chaining hash approaches that of open addressing hash on string keys but much slower on integer keys.</li>
<li><strong>Memory usage of search trees. </strong>B-tree is the winner here. Each element in the B-tree only needs one additional pointer. When there are enough elements, a B-tree is at least halfly full; on average it should be around 75% full. And so on 64-bit systems, for a B-tree with N elements, we need additional N*8/0.75=10N bytes memory. Splay tree will need N*8*2=16N extra space. RB tree is the worst.</li>
<li><strong>Other issues.</strong> a) Google hash becomes unbearably slow when I try to put a lot of strings in the hash table. All the other libraries do not have this problem. b) Google hash performs more comparisons than khash. This is obvious because google-dense is clearly faster on integer keys but comparable to khash on string keys.</li>
</ul>
<p><strong>Concluding remarks</strong></p>
<ul>
<li>C++ hash library is much easier to use than C libraries. This is definitely where C++ is preferred over C.</li>
<li>TR1 hash implementation is no faster than STL implementation. They may outperform one another under certain input or settings.</li>
<li>SGI hash_map is faster and takes less memory than STL map. Unless ordering is important, hash_map is a better container than map.</li>
<li>Google hash is a worthy choice when we understand why it is slow for many string keys.</li>
<li>My khash library, which is a single-file C++ template header, achieves good balance between speed and memory. All my source codes are available at the <a href="http://attractivechaos.wordpress.com/programs/">Programs page</a>.</li>
</ul>
<p><strong>Update</strong></p>
<ol>
<li>C interface can be elegant, too, if we implement it cleverly. See <a href="http://attractivechaos.wordpress.com/2008/09/02/implementing-generic-hash-library-in-c/">this post</a>.</li>
<li>I realize that we just need one lookup to achieve &#8220;insert if absent; delete otherwise&#8221;. This further improves the speed for all C++ libraries.</li>
<li>I have analyzed google dense hash table in <a href="http://attractivechaos.wordpress.com/2008/09/12/the-google-hash-table-library/">this post</a> which explains why it is faster than khash on integer keys but close to or slower than on string keys.</li>
<li><a href="http://compilers.iecc.com/comparch/article/07-04-089">This thread</a> directed me to <a href="http://gcc.gnu.org/viewcvs/trunk/libiberty/hashtab.c?view=log">gcc hashtable</a>, and <a href="http://cocom.cvs.sourceforge.net/cocom/cocom/AMMUNITION/">cocom hashtable</a>. They are more or less independent of other source codes, but it would still take time to separate the source codes. So, I have not benchmarked them. Just keep a record.</li>
<li> <a href="http://svn.python.org/view/python/trunk/Objects/">Python dictionary</a> is in fact a hash table. The <a href="http://svn.python.org/view/python/trunk/Objects/dictnotes.txt?rev=53782&amp;view=markup">dictnotes.txt</a> in that directory gives some quite interesting discussion about how to implement hash efficiently.</li>
<li><a href="http://cbfalconer.home.att.net/download/">hashlib</a> library. A bit hard to use and I cannot get it running correctly. Possibly I have not provided a proper second hash function for rehashing.</li>
<li>Added results for STL set (based on red-black tree) and John-Mark Gurney&#8217;s <a href="http://resnet.uoregon.edu/~gurney_j/jmpc/btree.html">B-tree implementation</a> (JG&#8217;s btree). Both libraries are considerably slower than hash tables. Of course search trees provide more functionality than hash tables, and every nice thing comes with a price. I have also tried Jason Evans&#8217;s and Niels Provos&#8217; red-black tree implementations. On integer keys, JE&#8217;s takes 6.110 seconds on Mac-Intel using 18.884 MB memory and NP&#8217;s taks 6.611 seconds using the same amount of memory. This performance is close to that of STL set. They appear to be slower mainly due to the additional malloc/free calls I have to made under their APIs. Unlike hash table which have a variety of ways to implement it, red-black tree usually has one way (well, can be more. See also Jason&#8217;s blog.). And so I only show the performance of STL set as a representitive.</li>
<li>Replaced JG&#8217;s B-tree with a modified version. The new version is both faster and more light-weighted.</li>
</ol>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/attractivechaos.wordpress.com/278/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/attractivechaos.wordpress.com/278/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/attractivechaos.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/attractivechaos.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/attractivechaos.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/attractivechaos.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/attractivechaos.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/attractivechaos.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/attractivechaos.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/attractivechaos.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/attractivechaos.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/attractivechaos.wordpress.com/278/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=attractivechaos.wordpress.com&blog=4545823&post=278&subd=attractivechaos&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://attractivechaos.wordpress.com/2008/08/28/comparison-of-hash-table-libraries/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/047ebc7bb9ff37a0da844413856e92cb?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">attractivechaos</media:title>
		</media:content>
	</item>
	</channel>
</rss>