<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title>blog</title>
  <link href="https://tiehu.is/"/>
  <id>https://tiehu.is/</id>
  <updated>2019-06-10T00:00:00Z</updated>
  <author>
    <name>Marc Tiehuis</name>
  </author>
<entry>
  <title>A Simpler Blog</title>
  <link href="https://tiehu.is/blog/blog1"/>
  <id>https://tiehu.is/blog/blog1</id>
  <updated>2019-05-13T00:00:00Z</updated>
  <content type="html"><![CDATA[
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="author" content="Marc Tiehuis">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Ramblings mostly about programming.">
    <title>blog</title>
    <style>
       html, body         { font-family: sans-serif; font-size: small; line-height: 1.5; }
       h1, h2, h3         { margin-top: 2em; }
       h3, h4, h5         { color: #2d58b7; }
       h1:nth-of-type(1)  { margin-top: 0.7em; margin-bottom: 0em; text-align: right; }
       pre > code         { display: block; overflow: auto; padding: 0.3em; }
       code               { background-color: snow; font-size: 13px; }
      .published          { margin-bottom: 4em; text-align: right; }
      .post, .home        { margin-left: auto; margin-right: auto; }
      .home-link          { float:left; margin-top: 0.7em; }
      .footer             { text-align: center; margin-top: 3em; margin-bottom: 1.5em; }

      @media screen and (min-width: 45em) {
        .post, .home, .central-element { width: 50em; } }

      @media screen and (max-width: 45em) {
         code { font-size: small; }
        .post, .home, .central-element { width: 92%; }
      }

      @media (prefers-color-scheme: dark) {
        filter: invert(80%); background-color: black; }
    </style>
  </head>
  <body>
    <div class="post">
      <div class="home-link"><a href="/">home</a></div>
<h1>A Simpler Blog</h1>
<div class="published"><time datetime="2019-05-13">13 May 2019</time></div>
<p>Previously I was using Jekyll for this blog. It worked okay but I disliked
having the ruby dependencies and felt it was a bit too complicated for
my intended use-case.</p>
<p>This was my <code>Gemfile.lock</code> prior to the change:</p>
<pre><code>GEM
  remote: https://rubygems.org/
  specs:
    addressable (2.5.0)
      public_suffix (~&gt; 2.0, &gt;= 2.0.2)
    colorator (1.1.0)
    ffi (1.9.17)
    forwardable-extended (2.6.0)
    jekyll (3.3.1)
      addressable (~&gt; 2.4)
      colorator (~&gt; 1.0)
      jekyll-sass-converter (~&gt; 1.0)
      jekyll-watch (~&gt; 1.1)
      kramdown (~&gt; 1.3)
      liquid (~&gt; 3.0)
      mercenary (~&gt; 0.3.3)
      pathutil (~&gt; 0.9)
      rouge (~&gt; 1.7)
      safe_yaml (~&gt; 1.0)
    jekyll-feed (0.9.2)
      jekyll (~&gt; 3.3)
    jekyll-last-modified-at (1.0.1)
      jekyll (~&gt; 3.3)
      posix-spawn (~&gt; 0.3.9)
    jekyll-sass-converter (1.5.0)
      sass (~&gt; 3.4)
    jekyll-watch (1.5.0)
      listen (~&gt; 3.0, &lt; 3.1)
    kramdown (1.13.2)
    liquid (3.0.6)
    listen (3.0.8)
      rb-fsevent (~&gt; 0.9, &gt;= 0.9.4)
      rb-inotify (~&gt; 0.9, &gt;= 0.9.7)
    mercenary (0.3.6)
    pathutil (0.14.0)
      forwardable-extended (~&gt; 2.6)
    posix-spawn (0.3.13)
    public_suffix (2.0.5)
    rb-fsevent (0.9.8)
    rb-inotify (0.9.7)
      ffi (&gt;= 0.5.0)
    rouge (1.11.1)
    safe_yaml (1.0.4)
    sass (3.4.23)

PLATFORMS
  ruby

DEPENDENCIES
  jekyll
  jekyll-feed
  jekyll-last-modified-at

BUNDLED WITH
1.15.2
</code></pre>
<p>I replaced all this with the following dependencies:</p>
<ul>
<li><a href="https://github.com/commonmark/cmark">cmark</a></li>
<li>make (GNU)</li>
<li>bash</li>
<li>inotify (optional)</li>
</ul>
<p>All these are found on any typical linux installation except cmark, which is a
small C library/executable that only requires libc.</p>
<p>Github by default builds your Jekyll pages repository. Since I no longer use it, I
now need to run <code>make</code> and build the html pages prior to pushing, but I
consider this minimal extra cost. Further, it allows me to support mirroring
this blog automatically to <a href="https://tiehuis.gitlab.io">gitlab pages</a>, which
do not support Jekyll. This is a very simple setup. I added a <code>.gitlab-ci.yml</code>
file, then enabled auto-mirroring in gitlab and pointed it to the repository on
github. I finally configured Gitlab’s CI to run on each commit.</p>
<p>I considered writing raw html directly and having no markdown to html step but
this seemed a bit too far. Minor things such as escaping code blocks and
maintaining open/end tags kept me with markdown. My index page currently is
raw html but I consider this a one-off (besides updating the index). The styling
also is slightly different to the standard post.</p>
<p>I briefly considered using a simple template system, but considering my needs I
decided against that and simply concatenate a few html files to build the
resulting posts. You can see this in the Makefile (which contains only one
essential step):</p>
<pre><code>MD := $(wildcard ./blog/*.md)
TMPL := $(wildcard ./build/*)
HTML := $(MD:.md=.html)

build: $(HTML)

blog/%.html: blog/%.md $(TMPL)
	@echo $&lt;
	@bash -c 'cat ./build/1.html ./build/1.css ./build/2.html &lt;(cmark --unsafe --smart $&lt;) ./build/3.html &gt; $@'

watch:
	@while inotifywait -qq -e move -e modify -e create -e delete --exclude './blog/*.html' ./blog; do \
		make -s; \
	done

.PHONY: watch
</code></pre>
<p>Finally, a change I had been meaning to do for a while anyway was to adjust the
path of the blog entries behind the <code>/blog</code> path. I’ve kept the existing links
as extra html pages which perform a simple <code>http-equiv=&quot;refresh&quot;</code> redirect to
the new pages so existing linked content will still continue to work.</p>
<p>I’m pretty happy with the result. There is less to go wrong here for me and I’ve
kept practically all of the same functionality (besides an auto-generated atom
feed) while minimizing dependencies. I’d strongly urge people to take a step
back every now and then and see if there current solution isn’t too much for
them and if it can’t be replaced. I spent a fair bit of time reading Jekyll
documentation, looking for plugins that I don’t need and determining how the
templating system worked. At least for my use-case, all I really needed was to
generate html from markdown and cat some files together.</p>
    </div>
    <div class="footer">
      <a href="/">home</a> - <a href="https://github.com/tiehuis/">github</a> - <a href="/atom.xml">rss</a> <br/>
    </div>
  </body>
</html>
]]>  </content>
</entry>
<entry>
  <title>Generic Data Structures in C</title>
  <link href="https://tiehu.is/blog/c1"/>
  <id>https://tiehu.is/blog/c1</id>
  <updated>2017-04-22T00:00:00Z</updated>
  <content type="html"><![CDATA[
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="author" content="Marc Tiehuis">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Ramblings mostly about programming.">
    <title>blog</title>
    <style>
       html, body         { font-family: sans-serif; font-size: small; line-height: 1.5; }
       h1, h2, h3         { margin-top: 2em; }
       h3, h4, h5         { color: #2d58b7; }
       h1:nth-of-type(1)  { margin-top: 0.7em; margin-bottom: 0em; text-align: right; }
       pre > code         { display: block; overflow: auto; padding: 0.3em; }
       code               { background-color: snow; font-size: 13px; }
      .published          { margin-bottom: 4em; text-align: right; }
      .post, .home        { margin-left: auto; margin-right: auto; }
      .home-link          { float:left; margin-top: 0.7em; }
      .footer             { text-align: center; margin-top: 3em; margin-bottom: 1.5em; }

      @media screen and (min-width: 45em) {
        .post, .home, .central-element { width: 50em; } }

      @media screen and (max-width: 45em) {
         code { font-size: small; }
        .post, .home, .central-element { width: 92%; }
      }

      @media (prefers-color-scheme: dark) {
        filter: invert(80%); background-color: black; }
    </style>
  </head>
  <body>
    <div class="post">
      <div class="home-link"><a href="/">home</a></div>
<h1>Generic Data Structures in C</h1>
<div class="published"><time datetime="2017-04-22">22 April 2017</time></div>
<p><small><em>See <a href="https://gist.github.com/tiehuis/6e10dfa4a36c1f414b3119dd1b77fa6b">here</a>
for a final implementation if you don’t want to read all this.</em></small></p>
<p>Generic data structures in C typically have a pretty unfriendly API. They
either rely on void pointers and erase type information, or resort to macros
to provide a semblance of the templating system found in C++.</p>
<p>This post will look at constructing a macro-based vector in C with a focus on
ease of use. We will use modern C11 features and ample compiler extensions to
see where we can take this.</p>
<h2>A Generic Vector</h2>
<p>First, lets define our vector type. We’ll call it <code>qvec</code> because its
short and sweet.</p>
<pre><code class="language-c">#define qvec(T)             \
    struct qvec_##T {       \
        size_t cap, len;    \
        T data[];           \
    }
</code></pre>
<p>We take a parameter <code>T</code> which will represent the type that is stored in our
vector. This will be templatized at compile-time, similar to how <code>vector&lt;T&gt;</code> is
in C++.</p>
<p>The <code>data</code> field is a <a href="https://en.wikipedia.org/wiki/Flexible_array_member">flexible array
member</a>
from C99.</p>
<p><small><em>Note: We will forgo error checking of <code>malloc</code> and <code>realloc</code>
for simplicity.</em></small></p>
<h3><code>new</code></h3>
<p>The <code>new</code> function should <code>malloc</code> enough memory for some initial members.
The size of the required storage will depend on the size of <code>T</code>. A possible
implementation could be</p>
<pre><code class="language-c">#define qvec_new(T, v)                                       \
do {                                                         \
    size_t initial_size = 16;                                \
    v = malloc(sizeof(qvec(T)) + sizeof(T) * initial_size);  \
    v-&gt;cap = initial_size;                                   \
    v-&gt;len = 0;                                              \
} while (0)
</code></pre>
<p>which we can use to initialize a vector of integers as</p>
<pre><code class="language-c">qvec(int) *v;
qvec_new(int, v);
</code></pre>
<p>The flexible array member allows us to get away with a single call to <code>malloc</code>
which is a minor nicety. Otherwise, this is a little underwhelming. The
separation of declaration and initialization is not ideal.</p>
<p>To make this a bit nicer, we can use <a href="https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs">statement expressions</a>
which allow multiple statements to be evaluated and used as if they were an
expression. Our new definition for <code>new</code> would then be</p>
<pre><code class="language-c">#define qvec_new(T)                                                           \
({                                                                            \
    const size_t initial_size = 16;                                           \
    struct qvec_##T *v = malloc(sizeof(qvec(T)) + sizeof(T) * initial_size);  \
    v-&gt;cap = initial_size;                                                    \
    v-&gt;len = 0;                                                               \
    v;                                                                        \
})
</code></pre>
<p>which gives us the much more natural usage</p>
<pre><code class="language-c">qvec(int) *v = qvec_new(int);
</code></pre>
<h2>Standard Functions</h2>
<p>Lets now implement the common vector functions <code>push</code>, <code>pop</code> and <code>at</code>.</p>
<h3><code>pop</code></h3>
<p><code>pop</code> doesn’t require any special knowledge of the type <code>T</code> so this is simply</p>
<pre><code class="language-c">#define qvec_pop(v) (v-&gt;data[--v-&gt;len])
</code></pre>
<h3><code>at</code></h3>
<p><code>at</code> is slightly more interesting. When working with a C++ vector (or a
standard C array), the notation <code>array[x]</code> is an <code>lvalue</code> which can be
assigned to. It would be nice if our <code>qvec</code> has this property as well.</p>
<p>First, lets define the helper function</p>
<pre><code class="language-c">#define qvec_ref(v, i) (&amp;v-&gt;data[i])
</code></pre>
<p>This returns an <code>lvalue</code> and so can be used with a pointer dereference. e.g.
<code>*qvec_ref(v, i) = 5</code>.</p>
<p>We can wrap this in another macro to hide this dereference</p>
<pre><code class="language-c">#define qvec_at(v, i) (*(qvec_ref(v, i)))
</code></pre>
<h3><code>push</code></h3>
<p><code>push</code> presents a small problem. If we were to generate a standard
implementation</p>
<pre><code class="language-c">#define qvec_push(v, i)                                 \
({                                                      \
    if (v-&gt;len &gt;= v-&gt;cap) {                             \
        v-&gt;cap *= 2;                                    \
        v = realloc(v, sizeof(?) + v-&gt;cap * sizeof(?)); \
    }                                                   \
    v-&gt;data[v-&gt;len++] = (i);                            \
})
</code></pre>
<p>we might be left wondering what to insert into the <code>?</code> marked locations.</p>
<p>The second <code>?</code> is less worrying. This should be <code>sizeof(T)</code>. We could just pass
the type again, but doing it on every push is not ideal. In fact, we don’t need
any new information. Recall that the <code>data</code> field of <code>qvec</code> is of type <code>T[]</code>.
Performing a dereference of this will give us the size of a single <code>T</code>, exactly
what we want!</p>
<p>The first <code>?</code> is more bothersome. We are interested in determining the value of
<code>sizeof(qvec(T))</code>. We can’t use the <code>data</code> field here, since the <code>T</code> required
here is the actual typename used during initialization. This would be viable if
it were possible to generate a type name from an arbitrary variable but
unfortunately we cannot do this.</p>
<p>The way to get this size is first to realise that the <code>data</code> member in a <code>qvec</code>
doesn’t actually take up any space within the array, not even for a pointer.</p>
<p>We can confirm this by checking the following</p>
<pre><code class="language-c">struct {
    char a, b;
    char b[]
} foo;

printf(&quot;foo is %zu bytes\n&quot;, sizeof(foo));
</code></pre>
<p>which will print</p>
<pre><code>foo is 2 bytes
</code></pre>
<p>Since this <code>data</code> doesn’t take any space, we can see that the other members
(<code>len</code> and <code>cap</code>) have a fixed type and therefore size, regardless of the type
of <code>T</code>.</p>
<p>We can separate the type of <code>qvec</code> into</p>
<pre><code class="language-c">#define qvec_base       \
    struct {            \
        size_t cap, len;\
    }

#define qvec(T)         \
    struct qvec_##T {   \
        qvec_base;      \
        T data[];       \
    }
</code></pre>
<p>This now allows us to query the size of the type-independent part of a <code>qvec</code>
while retaining access to all the members in the same way.</p>
<p>As an aside, we can define this using less macro-wizardry if we enable the
<code>-fplan9-extensions</code> option in GCC as documented <a href="https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html">here</a>.</p>
<pre><code class="language-c">struct qvec_base {
    size_t cap, len;
}

#define qvec(T)             \
    struct qvec_##T {       \
        struct qvec_base;   \
        T data[];           \
    }
</code></pre>
<p>This allows embedding of existing struct definitions as an anonymous struct.</p>
<p>Now, finally, we can define our <code>push</code> function as:</p>
<pre><code class="language-c">#define qvec_push(v, i)                                                 \
({                                                                      \
    if (v-&gt;len &gt;= v-&gt;cap) {                                             \
        v-&gt;cap *= 2;                                                    \
        v = realloc(v, sizeof(qvec_base) + v-&gt;cap * sizeof(*v-&gt;data));  \
    }                                                                   \
    v-&gt;data[v-&gt;len++] = (i);                                            \
})
</code></pre>
<h3><code>free</code></h3>
<p>Since we only use a single <code>malloc</code> to initialize the type, this is simply</p>
<pre><code class="language-c">#define qvec_free(v) free(v)
</code></pre>
<h3>API so far</h3>
<p>Lets see what this gives us so far</p>
<pre><code class="language-c">qvec(int) *iv = qvec_new(int);
qvec_push(iv, 5);
qvec_push(iv, 8);
printf(&quot;%d\n&quot;, qvec_at(iv, 0));
qvec_at(iv, 1) = 5;
qvec_free(iv);
</code></pre>
<p>and compared similar C++ vector usage</p>
<pre><code class="language-c++">std::vector&lt;int&gt; iv;
iv.push_back(5);
iv.push_back(8);
printf(&quot;%d\n&quot;, iv[0]);
iv[1] = 5;
</code></pre>
<p>Looking okay, but lets go a bit further.</p>
<h2>Extended Functions</h2>
<h3>Generic Printing</h3>
<p>It is fairly common that we want to dump the values of a vector to see what is
inside. If we wanted to write this for an integer vector, the following would
work</p>
<pre><code class="language-c">#define qvec_int_print(v)               \
({                                      \
    printf(&quot;[&quot;);                        \
    for (int i = 0; i &lt; v-&gt;len; ++i) {  \
        printf(&quot;%d&quot;, v-&gt;data[i]);       \
        if (i + 1 &lt; v-&gt;len)             \
            printf(&quot;, &quot;);               \
    }                                   \
    printf(&quot;]\n&quot;);                      \
})
</code></pre>
<p>which can be used as</p>
<pre><code class="language-c">qvec_print(iv); // [5, 5]
</code></pre>
<p>This is nice, but since it isn’t generic it has a limited use case. Fortunately
for us, C11 brings some new interesting features to the table which we can use.</p>
<p>The C11 <code>_Generic</code> keyword allows rudimentary switching based on the type of
its input. Think of it just as a <strong>compile-time switch statement on types</strong>.</p>
<p>For example, we could construct a macro to print the name of a type</p>
<pre><code class="language-c">#define type_name(x) _Generic((x), int: &quot;int&quot;, float: &quot;float&quot;)

printf(&quot;This is a %s\n&quot;, type_name(5.0f));
printf(&quot;This is a %s\n&quot;, type_name(5));
</code></pre>
<p>which when run would output</p>
<pre><code>This is a float
This is a int
</code></pre>
<p>We can use this to generate the appropriate <code>printf</code> format specifier for the
passed type.</p>
<pre><code class="language-c">#define GET_FMT_SPEC(x) _Generic((x), int: &quot;%d&quot;, float: &quot;%f&quot;, char*: &quot;%s&quot;)
</code></pre>
<p>and modifying our print function</p>
<pre><code class="language-c">#define qvec_print(v)                   \
({                                      \
    printf(&quot;[&quot;);                        \
    for (int i = 0; i &lt; v-&gt;len; ++i) {  \
        printf(GET_FMT_SPEC(v-&gt;data[i]), v-&gt;data[i]);\
        if (i + 1 &lt; v-&gt;len)             \
            printf(&quot;, &quot;);               \
    }                                   \
    printf(&quot;]\n&quot;);                      \
 })
</code></pre>
<p>This would now work on an integer and float <code>qvec</code> type with no modifications.
Of course, we could extend <code>GET_FMT_SPEC</code> with whatever types we need.</p>
<p><em>You may recall that I mentioned that we could solve an earlier issue regarding
our <code>push</code> function if we could generate a type name from a variable. It seems
like the <code>_Generic</code> keyword would help is achieve this and indeed it does in
part. The problem is that it is evaluated after preprocessing, so we cannot use
its output as part of the preprocessor token concatenation process.</em></p>
<p><em>This is an easy mistake to make, since <code>_Generic</code> is seen pretty much solely
within macro definitions for obvious reasons. This isn’t required though,
the following being perfectly valid code.</em></p>
<pre><code class="language-c">int a;
float b;

printf(&quot;%s\n&quot;, _Generic(a, int: &quot;a is an int&quot;, float: &quot;a is a float&quot;));
printf(&quot;%s\n&quot;, _Generic(b, int: &quot;b is an int&quot;, float: &quot;b is a float&quot;));
</code></pre>
<h2>Initializer Lists</h2>
<p>Since C++11, vectors can now be initialized with initializer lists</p>
<pre><code class="language-c++">std::vector&lt;int&gt; = {4, 5, 2, 3};
</code></pre>
<p>This is pretty nice. Let’s add something similar to our <code>new</code> function using
C99 variadic macros with a <a href="https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html">GCC extension</a>
which allows an arbitrary name to be given for them.</p>
<pre><code class="language-c">#define QVEC_ALEN(a) (sizeof(a) / sizeof(*a))

#define qvec_new(T, xs...)                                                    \
({                                                                            \
    const size_t initial_size = 16;                                           \
    const T _xs[] = {xs};                                                     \
    struct qvec_##T *v = malloc(sizeof(qvec(T)) + sizeof(T) * QVEC_ALEN(_xs));\
    v-&gt;cap = initial_size;                                                    \
    v-&gt;len = QVEC_ALEN(_xs);                                                  \
    for (int i = 0; i &lt; v-&gt;len; ++i)                                          \
        v-&gt;data[i] = _xs[i];                                                  \
    v;                                                                        \
})
</code></pre>
<p><code>xs</code> here collects all arguments except the first. We assign these to a
temporary array which allows us to work with the values, but also has the effect
of typechecking the values.</p>
<pre><code class="language-c">qvec(int) *v = qvec_new(int, 4, 5, 2, 3);
</code></pre>
<h2>Complex Objects</h2>
<p>Suppose we have the following type</p>
<pre><code class="language-c">typedef struct {
    char *id;
    bool is_tasty;
} Food;
</code></pre>
<p>We might try and utilize C99 struct initializers to perform the following</p>
<pre><code class="language-c">qvec(Food) *v = qvec_new(Food);
qvec_push(v, { .id = &quot;apple&quot;, .is_tasty = true });
</code></pre>
<p>This however fails to compile. Under clang, we get the following error</p>
<pre><code class="language-text">qvec.c:103:34: error: too many arguments provided to function-like macro
      invocation
    qvec_push(v, { &quot;apple&quot;, 1 });
                                 ^
qvec.c:42:9: note: macro 'qvec_push' defined here
#define qvec_push(v, i)                                                       \
        ^
qvec.c:103:5: note: cannot use initializer list at the beginning of a macro
      argument
    qvec_push(v, { &quot;apple&quot;, 1 });
    ^            ~~~~~~~~~~~~~~~~~~~~
qvec.c:103:5: error: use of undeclared identifier 'qvec_push'
    qvec_push(v, { &quot;apple&quot;, 1 });
    ^
</code></pre>
<p>The reason this doesn’t work is that the C preprocessor is dumb. It doesn’t know
that this is a designated initializer because it doesn’t actually know anything
about the C language. Instead, it sees two arguments. The first being
<code>{ .id = &quot;apple&quot;</code> and the second <code>.is_tasty = true }</code>.</p>
<p>The can get around this is by using the previously mentioned variadic macros once
again. Using a similar technique to the previously extended <code>new</code> function.</p>
<pre><code class="language-c">#define qvec_push(v, xs...)                                             \
({                                                                      \
    const typeof(*v-&gt;data) _xs[] = {xs};                                \
    if (v-&gt;len + QVEC_ALEN(_xs) &gt;= v-&gt;cap) {                            \
        while (v-&gt;cap &lt;= v-&gt;len + alen(_xs)) {                          \
            v-&gt;cap = 2 * v-&gt;cap;                                        \
        }                                                               \
        v = realloc(v, sizeof(qvec_base) + v-&gt;cap * sizeof(*v-&gt;data));  \
    }                                                                   \
    for (int i = 0; i &lt; QVEC_ALEN(_xs); ++i) {                          \
        v-&gt;data[v-&gt;len++] = _xs[i];                                     \
    }                                                                   \
    v;                                                                  \
})
</code></pre>
<p>The reason variadic macros help here is that all macro arguments are gathered at
once and treated as input to an array initializer. Even though individual
arguments are not valid tokens, it doesn’t matter, since the full set of
argments is.</p>
<p>Another thing to note is the use of the
<a href="https://gcc.gnu.org/onlinedocs/gcc/Typeof.html#Typeof"><code>typeof</code></a> keyword. This
allows us to retrieve the type of an expression, which can be used to initialize
new types. The most common example of its usage is likely within a type-generic
swap macro.</p>
<pre><code class="language-c">#define swap(x, y)              \
do {                            \
    const typeof(x) _temp = y;  \
    y = x;                      \
    x = _temp;                  \
} while (0)
</code></pre>
<h2>Extensions, Extensions, Extensions</h2>
<p>Our code is already filled with compiler-specific C extensions, so we may as
well go overboard.</p>
<h3>RAII</h3>
<p>One of the better features of C++ is the ability to utilize RAII to run
destructors on block exit. This reduces the chance that leaks occur within
programs and just makes using complex types much more pleasant.</p>
<p>The
<a href="https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Common-Variable-Attributes.html"><code>cleanup</code></a>
variable attribute is a GCC extension which allows a user-defined cleanup
function to automatically run when the value goes out of scope.</p>
<p>This attribute takes one argument, a function of type <code>void cleanup(T**)</code> where
<code>T</code> is the type which this attribute is declared with.</p>
<p>Using this with our <code>qvec</code>, it may look like</p>
<pre><code class="language-c">static inline _qvec_free(void **qvec) { free(*qvec); }

int main(void)
{
    qvec(int) __attribute__ ((cleanup(_qvec_free))) *qv = qvec_new(int);
    // No qvec_free here!
}
</code></pre>
<p>This is a little verbose however, so lets define our own <em>keyword</em> which we can
use instead.</p>
<pre><code class="language-c">#define raii __attribute__ ((cleanup(_qvec_free)))

int main(void)
{
    raii qvec(int) *qv = qvec_new(int);
}
</code></pre>
<p>Note that an attribute doesn’t strictly need to be specified after the type
definition.</p>
<p>This is nice, but if you had actually compiled the above you would get a number
of type errors.</p>
<pre><code>qvec.c: In function ‘main’:
qvec.c:13:12: warning: passing argument 1 of ‘_qvec_free’ from incompatible pointer type [-Wincompatible-pointer-types]
     struct {                                                                  \
            ^
qvec.c:26:40: note: in expansion of macro ‘qvec_base’
     struct qvec_##T *v = malloc(sizeof(qvec_base) + sizeof(_xs));             \
                                        ^
qvec.c:94:25: note: in expansion of macro ‘qvec_new’
     raii qvec(int) *v = qvec_new(int);
                         ^
qvec.c:88:20: note: expected ‘void **’ but argument is of type ‘struct qvec_int **’
 static inline void _qvec_free(void **qvec) { free(*qvec); }
</code></pre>
<p>The compiler complains because we are relying on an implicit cast to void. We
know this is actually valid however, since every <code>qvec</code> is going to use a
single call to <code>free</code> in order to release its memory.</p>
<p>As far as I’m aware, this requires a pragma at the callsite to disable this
locally. This is quite inconvenient, and really loses out any usability that we
may have gained from using this. The following will compile without warnings</p>
<pre><code class="language-c">int main(void)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored &quot;-Wincompatible-pointer-types&quot;
    raii qvec(int) *v = qvec_new(int, 5, 4, 3);
#pragma GCC diagnotic pop
}
</code></pre>
<p>At this stage though, remembering to just manually free seems like a saner
choice.</p>
<h3>Type Inference</h3>
<p>One of the nice features of C++11 onwards is the revitalization of the <code>auto</code>
keyword. This now provides type inference which is very nice in a number of
circumstances.</p>
<p>If we look at our vector initialization</p>
<pre><code class="language-c">qvec(int) *v = qvec_new(int);
</code></pre>
<p>we clearly have a bit of redundancy. Unfortunately the C language doesn’t support
type inference… as part of the standard at least. An interesting extension is
the <a href="https://gcc.gnu.org/onlinedocs/gcc/Typeof.html"><code>_auto_type</code></a> keyword which
provides some limited type inference capabilities.</p>
<p>Since the <code>auto</code> keyword is practically useless, lets just redefine it</p>
<p><small><em>Redefining keywords is usually a <strong>very</strong> bad idea. Although, GCC
<a href="https://gcc.gnu.org/onlinedocs/cpp/Macros.html#Macros">will allow it</a>.</em></small></p>
<pre><code class="language-c">#define auto __auto_type

auto iv = qvec_new(int);
</code></pre>
<p>Although yet again, our expectations differ to reality. This will not compile!
The reason for this is that previously we were relying on the inline struct
definition of <code>qvec(T)</code> that was declared on every initialization. Without this
declaration, our new <code>auto</code> keyword cannot find any struct which matches the
return type and must fail.</p>
<p>As an example, the following works fine</p>
<pre><code class="language-c">qvec(int) *a = qvec_new(int);
auto b = qvec_new(int);
</code></pre>
<p>because the <code>qvec(int)</code> declared the struct, so the next <code>qvec</code> return type can
be deduced correctly. This is simply an inherent limitation with the tools we
have. A simple solution would be simply forward declare our structs.</p>
<pre><code class="language-c">qvec(int);

int main(void)
{
    auto a = qvec_new(int); // Ok!
}
</code></pre>
<p>But this is one extra line to type for each <code>qvec</code> type required!</p>
<h2>Drawbacks</h2>
<p>We have a pretty good set of functions associated with our <code>qvec</code> so far.
Usability is ok and we have a few of the more desirable features of C++ in our
hands within C.</p>
<p>Undoubtedly however, there are some inherent problems that we just can’t solve.</p>
<h3>Complex Container Types</h3>
<p>We can do the following in C++</p>
<pre><code class="language-c++">std::vector&lt;std::vector&lt;std::vector&lt;int&gt;&gt;&gt; v;
</code></pre>
<p>To do this with our <code>qvec</code> the following is required</p>
<pre><code class="language-c">typedef qvec(int) qvec_int;
typedef qvec(qvec_int) qvec_qvec_int;
qvec(qvec_qvec_int) *v = qvec_new(qvec_qvec_int);
</code></pre>
<p>Recall back to our <code>new</code> implementation. We generate a struct with a name
<code>qvec_##T</code> where <code>T</code> is the type. Since this is concatenated to make an
identifier, the types <em>must</em> be comprised only of characters which can exist
within an identifier (<code>[_0-9A-Za-z]</code>). Any types which use other characters,
such as functions, pointers and even our own <code>qvec</code> types must have a typedef
before we can use them.</p>
<p>As an example, the following</p>
<pre><code class="language-c">qvec(char**);
</code></pre>
<p>expands to the invalid struct declaration</p>
<pre><code class="language-c">struct qvec_char** {
    size_t cap, len;
    char* data[];
};
</code></pre>
<h3>Too Much Inlining</h3>
<p>Since we are dealing with macros, every call is going to generate the same code
at the call site. This isn’t too big a deal with our <code>qvec</code>, since a vector is
inherently pretty simple, but if we wanted to use the same techniques to
construct a generic hashmap, for example, the code duplication would be much
worse.</p>
<p>This is where the generic containers which rely on simply generating the
required functions for each type (see
<a href="https://attractivechaos.wordpress.com/2008/09/02/implementing-generic-hash-library-in-c/">khash</a>)
definitely have the upper hand.</p>
<p>These approaches however do lose out a bit in terms of the expressiveness of the
resulting API (which is our main focus here).</p>
<h3>Which Names are Which?</h3>
<p>Say we wanted to do the following contrived thing</p>
<pre><code class="language-c">void print(qvec(int) *v)
{
    qvec_print(v);
}

int main(void)
{
    qvec(int) *v = qvec_new(int, 1, 2, 3);
    print(v);
}
</code></pre>
<p>This will spew our a mess of errors about anonymous structs. The reason being is
that the <code>qvec(int)</code> in the <code>print</code> parameter list is declaring a new anonymous
struct, and the two <code>qvec(int)</code> declarations are completely different
structures.</p>
<p>This can be worked around by doing a typedef at the start of your file and using
this, but again at the cost of extra work for the programmer.</p>
<p>How about the following example. Will this <code>qvec_new</code> be aware of the type being
used within the <code>Foo</code> struct?</p>
<pre><code class="language-c">struct Foo {
    qvec(int) *values;
};

void foo_init(Foo *v)
{
    v-&gt;value = qvec_new(int);
}

int main(void)
{
    struct Foo f;
    foo_init(&amp;f);
}
</code></pre>
<p>This in fact will work potentially to some surprise. Even though this does, it
still highlights a pretty important problem. Even though the API is nice and
appears easy to use, there are a number of naming issues that the user must be
aware of, which greatly limits its usage as a <em>just works</em> type of structure.</p>
<h2>A Final Look</h2>
<pre><code class="language-c">#include &quot;qvec.h&quot;

typedef char* string;

typedef struct {
    int x, y;
} Tuple;

int main(void)
{
    qvec(string) *sv = qvec_new(string, &quot;Who&quot;, &quot;are&quot;, &quot;you?&quot;);
    qvec_print(sv);
    qvec_at(sv, 2) = &quot;we?&quot;;
    qvec_print(sv);
    qvec_free(sv);

    qvec(int) *iv = qvec_new(int, 1, 2, 3, 4);
    qvec_print(iv);
    printf(&quot;%d\n&quot;, qvec_pop(iv));
    qvec_free(iv);

    qvec(Tuple) *tv = qvec_new(Tuple, { .x = 0, .y = 1 }, { 4, 2 }, { 5, 4 });
    printf(&quot;%d\n&quot;, qvec_at(tv, 1).x);
    printf(&quot;%d\n&quot;, qvec_at(tv, 2).x);
    qvec_free(tv);
}
</code></pre>
<p>So would I recommend using this? Probably not. If you were insistent on
sticking with C however I think the best compromise would be to generate the
specific instantiations (similar to what <a href="https://attractivechaos.wordpress.com/2008/09/02/implementing-generic-hash-library-in-c/">khash</a>
does). This gets rid of most of the problems specified here. Alternatively,
if performance and the type-safety isn’t a big deal, then a tried and tested
<code>void*</code> implementation would be good too.</p>
<p>At the end of the day though, the pragmatic solution would be to just use C++
if there are no reasons not to and call it a day. Especially if you are
considering performing these types of C macro chicanery.</p>
    </div>
    <div class="footer">
      <a href="/">home</a> - <a href="https://github.com/tiehuis/">github</a> - <a href="/atom.xml">rss</a> <br/>
    </div>
  </body>
</html>
]]>  </content>
</entry>
<entry>
  <title>Lwan Api Intro</title>
  <link href="https://tiehu.is/blog/lwan1"/>
  <id>https://tiehu.is/blog/lwan1</id>
  <updated>2017-02-16T00:00:00Z</updated>
  <content type="html"><![CDATA[
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="author" content="Marc Tiehuis">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Ramblings mostly about programming.">
    <title>blog</title>
    <style>
       html, body         { font-family: sans-serif; font-size: small; line-height: 1.5; }
       h1, h2, h3         { margin-top: 2em; }
       h3, h4, h5         { color: #2d58b7; }
       h1:nth-of-type(1)  { margin-top: 0.7em; margin-bottom: 0em; text-align: right; }
       pre > code         { display: block; overflow: auto; padding: 0.3em; }
       code               { background-color: snow; font-size: 13px; }
      .published          { margin-bottom: 4em; text-align: right; }
      .post, .home        { margin-left: auto; margin-right: auto; }
      .home-link          { float:left; margin-top: 0.7em; }
      .footer             { text-align: center; margin-top: 3em; margin-bottom: 1.5em; }

      @media screen and (min-width: 45em) {
        .post, .home, .central-element { width: 50em; } }

      @media screen and (max-width: 45em) {
         code { font-size: small; }
        .post, .home, .central-element { width: 92%; }
      }

      @media (prefers-color-scheme: dark) {
        filter: invert(80%); background-color: black; }
    </style>
  </head>
  <body>
    <div class="post">
      <div class="home-link"><a href="/">home</a></div>
<h1>Lwan Api Intro</h1>
<div class="published"><time datetime="2017-02-16">16 Feb 2017</time></div>
<p><em><small>See <a href="https://github.com/tiehuis/lwan-api-example">this</a> repository for
a complete example project.</small></em></p>
<p><a href="https://lwan.ws/">Lwan</a> is a high performance &amp; scalable web server written in
C.</p>
<p><em>The main page has now been updated so the following is no longer applicable.
Skip to the <strong>Building</strong> section.</em></p>
<p>An API example is listed on the main project page.</p>
<pre><code class="language-c">#include &quot;lwan.h&quot;

static lwan_http_status_t
hello_world(lwan_request_t *request,
            lwan_response_t *response, void *data)
{
    static const char message[] = &quot;Hello, World!&quot;;

    response-&gt;mime_type = &quot;text/plain&quot;;
    strbuf_set_static(response-&gt;buffer, message, sizeof(message) - 1);

    return HTTP_OK;
}

int
main(void)
{
    const lwan_url_map_t default_map[] = {
        { .prefix = &quot;/&quot;, .handler = hello_world },
        { .prefix = NULL }
    };
    lwan_t l;

    lwan_init(&amp;l);

    lwan_set_url_map(&amp;l, default_map);
    lwan_main_loop(&amp;l);

    lwan_shutdown(&amp;l);

    return 0;
}
</code></pre>
<p>This looks great, easy to use and no real surprises. Unfortunately, this is
incompatible with the current master branch at the time of writing. Further,
the documentation on using Lwan as a library is a bit sparse at this time.</p>
<p>This will be a quick-start guide to setting up a sample project and going from
there.</p>
<h2>Building</h2>
<p>First, we’ll create a new project.</p>
<pre><code class="language-text">mkdir lwan-api-example
cd lwan-api-example
</code></pre>
<p>Next, let’s pull lwan into the project and build it. You will need CMake and
zlib installed for this.</p>
<pre><code class="language-text">git clone https://github.com/lpereira/lwan # Use a submodule here if using git!
cd lwan
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make
</code></pre>
<p>This generates <code>liblwan.a</code> and <code>liblwan.so</code> library files in the <code>build/common</code>
directory. We’ll come back to these later, lets start a simple project.</p>
<h2>Creating the project</h2>
<p>Let’s go back to our project root and create a new file, <code>hello.c</code>.</p>
<pre><code class="language-c">#include &lt;lwan.h&gt;

static enum lwan_http_status hello_world(
        struct lwan_request *request,
        struct lwan_response *response,
        void *data)
{
    static const char message[] = &quot;Hello, World!&quot;;

    response-&gt;mime_type = &quot;text/plain&quot;;
    strbuf_set_static(response-&gt;buffer, message, sizeof(message) - 1);

    return HTTP_OK;
}

int main(void)
{
    const struct lwan_url_map default_map[] = {
        { .prefix = &quot;/&quot;, .handler = hello_world },
        { .prefix = NULL }
    };

    struct lwan l;
    lwan_init(&amp;l);

    lwan_set_url_map(&amp;l, default_map);
    lwan_main_loop(&amp;l);

    lwan_shutdown(&amp;l);
    return 0;
}
</code></pre>
<p>Note that the main differences between the current api is the removal of <code>_t</code>
specifiers (likely for POSIX conformance).</p>
<h2>Building our project</h2>
<p>The include headers are stored in the <code>common</code> directory. We also require the
include header generated by CMake which is found in the <code>build</code> directory.</p>
<p>We then can build our project.</p>
<pre><code>gcc -O2 -Ilwan/common -Ilwan/build hello.c lwan/build/common/liblwan.a \
    -o hello -lpthread -ldl -lz
</code></pre>
<p>We need to remember to link the pthread, dl and zlib libraries. That should be
it, you should now have a binary <code>hello</code> that you can run.</p>
<p>Have fun!</p>
    </div>
    <div class="footer">
      <a href="/">home</a> - <a href="https://github.com/tiehuis/">github</a> - <a href="/atom.xml">rss</a> <br/>
    </div>
  </body>
</html>
]]>  </content>
</entry>
<entry>
  <title>PEG Grammar for Chord Notation</title>
  <link href="https://tiehu.is/blog/peg1"/>
  <id>https://tiehu.is/blog/peg1</id>
  <updated>2017-12-17T00:00:00Z</updated>
  <content type="html"><![CDATA[
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="author" content="Marc Tiehuis">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Ramblings mostly about programming.">
    <title>blog</title>
    <style>
       html, body         { font-family: sans-serif; font-size: small; line-height: 1.5; }
       h1, h2, h3         { margin-top: 2em; }
       h3, h4, h5         { color: #2d58b7; }
       h1:nth-of-type(1)  { margin-top: 0.7em; margin-bottom: 0em; text-align: right; }
       pre > code         { display: block; overflow: auto; padding: 0.3em; }
       code               { background-color: snow; font-size: 13px; }
      .published          { margin-bottom: 4em; text-align: right; }
      .post, .home        { margin-left: auto; margin-right: auto; }
      .home-link          { float:left; margin-top: 0.7em; }
      .footer             { text-align: center; margin-top: 3em; margin-bottom: 1.5em; }

      @media screen and (min-width: 45em) {
        .post, .home, .central-element { width: 50em; } }

      @media screen and (max-width: 45em) {
         code { font-size: small; }
        .post, .home, .central-element { width: 92%; }
      }

      @media (prefers-color-scheme: dark) {
        filter: invert(80%); background-color: black; }
    </style>
  </head>
  <body>
    <div class="post">
      <div class="home-link"><a href="/">home</a></div>
<h1>PEG Grammar for Chord Notation</h1>
<div class="published"><time datetime="2017-12-17">17 Dec 2017</time></div>
<p>Recently I was looking for a grammar to catagorize music chords but was
surprised that there weren’t any decent ones around.</p>
<p>The following is a PEG grammar which categorizes the most common cases for
standard Jazz notation. There are a few missing edge cases (e.g. 7sus4).</p>
<p>I’m still unsure whether a full grammar is worthwhile due to the many edge
cases. I’ve written a parser previously using <a href="https://github.com/tiehuis/quartic/blob/master/src/parser.rs">parser
combinators</a>
which was fairly straight-forward.</p>
<p>You can find an online peg parser generator <a href="https://pegjs.org/online">here</a>.</p>
<pre><code class="language-text">PolyChord          = Chord ('|' Chord)?
Chord              = Chord1 / Chord2 / Chord3 / Chord4

Chord1             = Note Special ChordUpper
Chord2             = Note ThirdSeventh Extended? ChordUpper
Chord3             = Note Third? Sixth ChordUpper
Chord4             = Note Third? Extended? ChordUpper

ChordUpper         = Addition? Alterations? Slash?
ThirdSeventh       = Augmented / Diminished
Augmented          = 'aug' / '+'
Diminished         = 'dim' / 'o' / 'ø'

Special            = '5' / 'sus2' / 'sus4'
Sixth              = '6' / '6/9'

Third              = (MajorThird !Extended) / MinorThird
MajorThird         = 'Maj' / 'M' / 'Δ'
MinorThird         = 'min' / 'm' / '-'

Extended           = ExtendedQuality? ExtendedInterval
ExtendedQuality    = MajorThird / 'dom'
ExtendedInterval   = '7' / '9' / '11' / '13'

Alterations        = Alteration / AlterationList
AlterationList     = '(' Alteration (',' Alteration)* ')'
Alteration         = Accidental AlterationInterval
AlterationInterval = '4' / '5' / '9' / '11' / '13'

Addition           = 'add' ('2' / '4' / '6')

Slash              = '/' Note Accidental?

Note               = [A-G] Accidental*
Accidental         = [b#]
</code></pre>
    </div>
    <div class="footer">
      <a href="/">home</a> - <a href="https://github.com/tiehuis/">github</a> - <a href="/atom.xml">rss</a> <br/>
    </div>
  </body>
</html>
]]>  </content>
</entry>
<entry>
  <title>Iterative Replacement of C with Zig</title>
  <link href="https://tiehu.is/blog/zig1"/>
  <id>https://tiehu.is/blog/zig1</id>
  <updated>2017-07-19T00:00:00Z</updated>
  <content type="html"><![CDATA[
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="author" content="Marc Tiehuis">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Ramblings mostly about programming.">
    <title>blog</title>
    <style>
       html, body         { font-family: sans-serif; font-size: small; line-height: 1.5; }
       h1, h2, h3         { margin-top: 2em; }
       h3, h4, h5         { color: #2d58b7; }
       h1:nth-of-type(1)  { margin-top: 0.7em; margin-bottom: 0em; text-align: right; }
       pre > code         { display: block; overflow: auto; padding: 0.3em; }
       code               { background-color: snow; font-size: 13px; }
      .published          { margin-bottom: 4em; text-align: right; }
      .post, .home        { margin-left: auto; margin-right: auto; }
      .home-link          { float:left; margin-top: 0.7em; }
      .footer             { text-align: center; margin-top: 3em; margin-bottom: 1.5em; }

      @media screen and (min-width: 45em) {
        .post, .home, .central-element { width: 50em; } }

      @media screen and (max-width: 45em) {
         code { font-size: small; }
        .post, .home, .central-element { width: 92%; }
      }

      @media (prefers-color-scheme: dark) {
        filter: invert(80%); background-color: black; }
    </style>
  </head>
  <body>
    <div class="post">
      <div class="home-link"><a href="/">home</a></div>
<h1>Iterative Replacement of C with Zig</h1>
<div class="published"><time datetime="2017-07-19">19 Jul 2017</time></div>
<p><a href="http://ziglang.org/">Zig</a> is a programming language in a similar realm as C.
Being more modern, it has a number of useful constructs such as sum types,
compile-time introspection, improved error handling and no preprocessor!</p>
<p>This post will not describe the language itself (check the project page for
that), but will show how it can be
used to convert an existing C code-base into zig. We will look at a simplistic
example, but the general strategy remains the same.</p>
<p>The <code>zig</code> compiler that will be used in this post can be found <a href="https://github.com/zig-lang/zig">here</a>.</p>
<p><em>The finished conversion result is at <a href="https://github.com/tiehuis/zig-replace-c">this</a>
repository. For each heading, there is a corresponding commit which describes
all changes made at each point in the conversion process.</em></p>
<h2>The Project</h2>
<p><small><a href="https://github.com/tiehuis/zig-replace-c/commit/572d12a60187799cacb649c44b0e2a8eb7be33c7">commit</a></small></p>
<p>The project we will be replacing has the following structure:</p>
<pre><code class="language-text">$ tree .
.
├── compute.c
├── compute.h
├── compute_helper.c
├── compute_helper.h
├── display.c
├── display.h
├── main.c
└── Makefile
</code></pre>
<p>The contents of the files are:</p>
<h4>main.c</h4>
<pre><code class="language-c">#include &quot;display.h&quot;
#include &quot;compute.h&quot;

int main(void)
{
    display_char(compute('A'));
}
</code></pre>
<h4>display.c</h4>
<pre><code class="language-c">#include &lt;stdio.h&gt;

void display_char(char c)
{
    printf(&quot;%c\n&quot;, c);
}
</code></pre>
<h4>compute.c</h4>
<pre><code class="language-c">#include &quot;compute_helper.h&quot;

char compute(char a)
{
    return compute_helper(a) + 5;
}
</code></pre>
<h4>compute_helper.c</h4>
<pre><code class="language-c">char compute_helper(char a)
{
    return a + 1;
}
</code></pre>
<h4>Makefile</h4>
<pre><code class="language-make">SRCS := compute.c compute_helper.c display.c main.c
OBJS := $(SRCS:%.c=build/%.o)

main: $(OBJS)
	gcc -o main $(OBJS)

$(OBJS): build/%.o: %.c | mkdirs
	gcc -std=c99 -c $&lt; -o $@

mkdirs:
	@mkdir -p build

clean:
	rm -rf build main
</code></pre>
<p>The <code>.h</code> file contents simply expose their corresponding <code>.c</code> implementations.</p>
<pre><code class="language-text">$ make
gcc -std=c99 -c compute.c -o build/compute.o
gcc -std=c99 -c compute_helper.c -o build/compute_helper.o
gcc -std=c99 -c display.c -o build/display.o
gcc -std=c99 -c main.c -o build/main.o
gcc -o main build/compute.o build/compute_helper.o build/display.o build/main.o

$ ./main
G
</code></pre>
<h2>The Zig Build System</h2>
<p><small><a href="https://github.com/tiehuis/zig-replace-c/commit/0704b4455bc23f1dae820fe2791dcc56368e7aaa">commit</a></small></p>
<p>The first thing we will change is replacing the <code>Makefile</code> with zigs own custom
build system. The build system of zig is written in zig itself, which reduces
the requirement of knowing the oft-arcane Makefile idiosyncrasies.</p>
<h4>build.zig</h4>
<pre><code class="language-text">const Builder = @import(&quot;std&quot;).build.Builder;

pub fn build(b: &amp;Builder) {
    const exe = b.addCExecutable(&quot;main&quot;);
    exe.addCompileFlags([][]const u8 {
        &quot;-std=c99&quot;
    });

    const source_files = [][]const u8 {
        &quot;compute.c&quot;,
        &quot;compute_helper.c&quot;,
        &quot;display.c&quot;,
        &quot;main.c&quot;
    };

    for (source_files) |source| {
        exe.addSourceFile(source);
    }

    exe.setOutputPath(&quot;./main&quot;);
    b.default_step.dependOn(&amp;exe.step);
}
</code></pre>
<p>First, we begin by specifying the main executable which we will be building.
This constructs an object which represents a build-step. For each source
file in our project, we simply add the file to main executable step.</p>
<p>This approach is far more imperative than the declarative approach of a
Makefile. In my view, this is a good choice. Makefiles whilst concise can
become exceedingly opaque and hard to parse, especially as a project grows and
extra conditions need to be handled.</p>
<pre><code class="language-text">$ zig build --verbose
cc -c compute.c -o zig-cache/compute.c.o -std=c99
cc -c compute_helper.c -o zig-cache/compute_helper.c.o -std=c99
cc -c display.c -o zig-cache/display.c.o -std=c99
cc -c main.c -o zig-cache/main.c.o -std=c99
cc zig-cache/compute.c.o zig-cache/compute_helper.c.o zig-cache/display.c.o \
    zig-cache/main.c.o -o main -Wl,-rpath,zig-cache -rdynamic

$ ./main
G
</code></pre>
<h2>First C Replacement</h2>
<p><small><a href="https://github.com/tiehuis/zig-replace-c/commit/c74cba439b36fa7f6de41a155f156c06083bccfb">commit</a></small></p>
<p>The first actual source code we will replace is <code>compute.c</code>.</p>
<h4>compute.zig</h4>
<pre><code class="language-text">use @cImport(@cInclude(&quot;compute_helper.h&quot;));

export fn compute(a: u8) -&gt; u8 {
    compute_helper(a) + 5
}
</code></pre>
<p>This snippet demonstrates a few features of zig. First, zig is able to parse
C header files directly. No binding interface needing! In this case, the <code>use</code>
statement will bring all definitions from <code>compute_helper.h</code> into the global
namespace, allowing us to call the <code>compute_helper</code> function.</p>
<p>The other important thing to note here is the <code>export</code> specifier on our function.
This is important as it tells zig that it should compile this against the C ABI.
This means we can call this function from within other C files.</p>
<p>Since our header files are simple, we can continue using them unmodified. Zig does
automatically generate C headers as well however. We can compare these against
the expected definitions to make sure that we implemented the function
correctly.</p>
<h4>zig-cache/compute.zig.h</h4>
<pre><code class="language-c">#ifndef COMPUTE_2E_ZIG_H
#define COMPUTE_2E_ZIG_H

#include &lt;stdint.h&gt;

#ifdef __cplusplus
#define COMPUTE_2E_ZIG_EXTERN_C extern &quot;C&quot;
#else
#define COMPUTE_2E_ZIG_EXTERN_C
#endif

#if defined(_WIN32)
#define COMPUTE_2E_ZIG_EXPORT COMPUTE_2E_ZIG_EXTERN_C __declspec(dllimport)
#else
#define COMPUTE_2E_ZIG_EXPORT COMPUTE_2E_ZIG_EXTERN_C __attribute__((visibility (&quot;default&quot;)))
#endif

COMPUTE_2E_ZIG_EXPORT uint8_t compute(uint8_t a);
COMPUTE_2E_ZIG_EXPORT __attribute__((__noreturn__)) void __zig_panic(const uint8_t * message_ptr, uintptr_t message_len);

#endif
</code></pre>
<h3>Build System Modification</h3>
<p>The second step we need to perform is modifying <code>build.zig</code> to compile both
C and zig files and link them together.</p>
<h4>build.zig</h4>
<pre><code class="language-text">const Builder = @import(&quot;std&quot;).build.Builder;

pub fn build(b: &amp;Builder) {
    const exe = b.addCExecutable(&quot;main&quot;);
    b.addCIncludePath(&quot;.&quot;);
    exe.addCompileFlags([][]const u8 {
        &quot;-std=c99&quot;
    });

    const source_files = [][]const u8 {
        &quot;compute_helper.c&quot;,
        &quot;display.c&quot;,
        &quot;main.c&quot;
    };

    for (source_files) |source| {
        exe.addSourceFile(source);
    }

    const zig_source_files = [][]const u8 {
        &quot;compute.zig&quot;,
    };

    for (zig_source_files) |source| {
        const object = b.addObject(source, source);
        exe.addObject(object);
    }

    exe.setOutputPath(&quot;./main&quot;);
    b.default_step.dependOn(&amp;exe.step);
}
</code></pre>
<p>This is mostly same, except we now have a list of zig source files as well. This
should be fairly self-explanatory; for each zig source, we create an object
build step. This is then added to the exe build step.</p>
<p>Note that we also add the current directory to the C include path. This is
important since the <code>@cInclude</code> function used by zig does not read headers from
the local directory.</p>
<pre><code class="language-text">$ zig build --verbose
zig build-obj compute.zig --cache-dir zig-cache --output zig-cache/compute.zig.o \
    --output-h zig-cache/compute.zig.h --name compute.zig -isystem .
cc -c compute_helper.c -o zig-cache/compute_helper.c.o -std=c99 -I zig-cache
cc -c display.c -o zig-cache/display.c.o -std=c99 -I zig-cache
cc -c main.c -o zig-cache/main.c.o -std=c99 -I zig-cache
cc zig-cache/compute.zig.o zig-cache/compute_helper.c.o zig-cache/display.c.o \
    zig-cache/main.c.o -o main -Wl,-rpath,zig-cache -rdynamic

$ ./main
G
</code></pre>
<h2>Using the Zig Standard Library</h2>
<p><small><a href="https://github.com/tiehuis/zig-replace-c/commit/8a8f571d7802dd416b81269830ccd7313b810b51">commit</a></small></p>
<p>The next file we will replace is <code>display.c</code>.</p>
<h4>display.zig</h4>
<pre><code class="language-text">const std = @import(&quot;std&quot;);
const printf = std.io.stdout.printf;

export fn display_char(c: u8)
{
    %%printf(&quot;{c}\n&quot;, c);
}
</code></pre>
<p>Since we want to end up using only zig, we can replace the C printf statement
with zig’s own stdlib implementation. Zig does not depend on libc at all.
Because this is the only use of libc in our project, we can use the <code>nostdlib</code>
to enforce this during our C compilation.</p>
<h4>build.zig</h4>
<pre><code class="language-text">exe.addCompileFlags([][]const u8 {
    &quot;-std=c99&quot;,
    &quot;-nostdlib&quot;,
});
</code></pre>
<p>The only other changes are removing <code>display.c</code> from the C sources, and adding
<code>display.zig</code> to the zig sources.</p>
<pre><code class="language-text">$ zig build --verbose
zig build-obj compute.zig --cache-dir zig-cache --output zig-cache/compute.zig.o \
    --output-h zig-cache/compute.zig.h --name compute.zig -isystem .
zig build-obj display.zig --cache-dir zig-cache --output zig-cache/display.zig.o \
    --output-h zig-cache/display.zig.h --name display.zig -isystem .
cc -c compute_helper.c -o zig-cache/compute_helper.c.o -std=c99 -nostdlib -I zig-cache -I zig-cache
cc -c main.c -o zig-cache/main.c.o -std=c99 -nostdlib -I zig-cache -I zig-cache
cc zig-cache/compute.zig.o zig-cache/display.zig.o zig-cache/compute_helper.c.o \
    zig-cache/main.c.o -o main -Wl,-rpath,zig-cache -rdynamic

$ ./main
G
</code></pre>
<h2>Removing Header Files</h2>
<p><small><a href="https://github.com/tiehuis/zig-replace-c/commit/e24d3141956521f7c950ce8ff8a48e6210fe2e4e">commit</a></small></p>
<p>As we get further along in our replacement, we will eventually reach the point
where we have zig files which are not used by any other C files. This is great
as it means we can remove the header files.</p>
<p>Consider now as we change <code>compute_helper.c</code>.</p>
<h4>compute_helper.zig</h4>
<pre><code class="language-text">pub fn compute_helper(a: u8) -&gt; u8
{
    a + 1
}
</code></pre>
<p>The only dependency on this is <code>compute.zig</code>. We don’t need to export this using
the C ABI and can just mark it <code>pub</code> for visibility. <code>compute.c</code> can then be
changed to import a zig file instead.</p>
<h4>compute.zig</h4>
<pre><code class="language-text">pub use @import(&quot;compute_helper.zig&quot;);

export fn compute(a: u8) -&gt; u8 {
    compute_helper(a) + 5
}
</code></pre>
<pre><code class="language-text">$ zig build --verbose
zig build-obj compute.zig --cache-dir zig-cache --output zig-cache/compute.zig.o \
    --output-h zig-cache/compute.zig.h --name compute.zig -isystem .
zig build-obj compute_helper.zig --cache-dir zig-cache --output zig-cache/compute_helper.zig.o \
    --output-h zig-cache/compute_helper.zig.h --name compute_helper.zig -isystem .
zig build-obj display.zig --cache-dir zig-cache --output zig-cache/display.zig.o \
    --output-h zig-cache/display.zig.h --name display.zig -isystem .
cc -c main.c -o zig-cache/main.c.o -std=c99 -nostdlib -I zig-cache -I zig-cache -I zig-cache
cc zig-cache/compute.zig.o zig-cache/compute_helper.zig.o zig-cache/display.zig.o \
    zig-cache/main.c.o -o main -Wl,-rpath,zig-cache -rdynamic

$ ./main
G
</code></pre>
<h2>The Final File</h2>
<p><small><a href="https://github.com/tiehuis/zig-replace-c/commit/1bbee329aebbbb8578623d4b8e1967904fa6dcb1">commit</a></small></p>
<p>Our project now has only 1 remnant left of C. Let’s remove it all!</p>
<h4>main.zig</h4>
<pre><code class="language-text">use @import(&quot;display.zig&quot;);
use @import(&quot;compute.zig&quot;);

pub fn main() -&gt; %void {
    display_char(compute('A'));
}
</code></pre>
<p>The main things to note here are the <code>use</code> statements for import. Since we were
converting a C project, we didn’t initially have any namespacing. Since zig has
a proper module system we usually strongly prefer assigning our imports to a
constant. e.g. <code>const display = @import(&quot;display.zig&quot;)</code>.</p>
<p>Now, we need to edit our <code>build.zig</code> file.</p>
<h4>build.zig</h4>
<pre><code>const Builder = @import(&quot;std&quot;).build.Builder;

pub fn build(b: &amp;Builder) {
    const exe = b.addExecutable(&quot;main&quot;, &quot;main.zig&quot;);

    exe.setOutputPath(&quot;./main&quot;);
    b.default_step.dependOn(&amp;exe.step);
}
</code></pre>
<p>Much simpler! Zig can make use of the implicit dependency graph formed between
imports. Individual object files do not need to be built for each file
explicitly.</p>
<pre><code class="language-text">$ zig build --verbose
zig build-exe main.zig --cache-dir zig-cache --output main --name main

./main
G
</code></pre>
<h2>Closing</h2>
<p>Zig makes this type of iterative conversion comparatively easier than most other
languages. For larger projects there will be unknown difficulties however. These
will be continually improved as the language becomes more stable and refined.</p>
<p>Being able to easily replace C with a newer modern alternative is a real bonus
in terms of safety and ergonomics. See this
<a href="http://andrewkelley.me/post/intro-to-zig.html">post</a> by the creator of the
language some short examples of improvements.</p>
<p>If you want to know more about zig as a language, check out the <a href="http://ziglang.org/">project
page</a>.</p>
    </div>
    <div class="footer">
      <a href="/">home</a> - <a href="https://github.com/tiehuis/">github</a> - <a href="/atom.xml">rss</a> <br/>
    </div>
  </body>
</html>
]]>  </content>
</entry>
<entry>
  <title>Big Integers in Zig</title>
  <link href="https://tiehu.is/blog/zig2"/>
  <id>https://tiehu.is/blog/zig2</id>
  <updated>2018-05-13T00:00:00Z</updated>
  <content type="html"><![CDATA[
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="author" content="Marc Tiehuis">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Ramblings mostly about programming.">
    <title>blog</title>
    <style>
       html, body         { font-family: sans-serif; font-size: small; line-height: 1.5; }
       h1, h2, h3         { margin-top: 2em; }
       h3, h4, h5         { color: #2d58b7; }
       h1:nth-of-type(1)  { margin-top: 0.7em; margin-bottom: 0em; text-align: right; }
       pre > code         { display: block; overflow: auto; padding: 0.3em; }
       code               { background-color: snow; font-size: 13px; }
      .published          { margin-bottom: 4em; text-align: right; }
      .post, .home        { margin-left: auto; margin-right: auto; }
      .home-link          { float:left; margin-top: 0.7em; }
      .footer             { text-align: center; margin-top: 3em; margin-bottom: 1.5em; }

      @media screen and (min-width: 45em) {
        .post, .home, .central-element { width: 50em; } }

      @media screen and (max-width: 45em) {
         code { font-size: small; }
        .post, .home, .central-element { width: 92%; }
      }

      @media (prefers-color-scheme: dark) {
        filter: invert(80%); background-color: black; }
    </style>
  </head>
  <body>
    <div class="post">
      <div class="home-link"><a href="/">home</a></div>
<h1>Big Integers in Zig</h1>
<div class="published"><time datetime="2018-05-13">13 May 2018</time></div>
<p>I’ve recently been writing a big-integer library, <a href="https://github.com/tiehuis/zig-bn">zig-bn</a>
in the <a href="https://ziglang.org/">Zig</a> programming language.</p>
<p>The goal is to have reasonable performance in a fairly simple implementation
with a generic implementation with no assembly routines.</p>
<p>I’ll list a few nice features about Zig which I think suit this sort of library
before exploring some preliminary performance comparisons and what in the
language encourages the speed.</p>
<h2>Transparent Local Allocators</h2>
<p>Unlike most languages, the Zig standard library does not have a default
allocator implementation. Instead, allocators are specified at runtime, passed
as arguments to parts of the program which require it. I’ve used the same idea
with this big integer library.</p>
<p>The nice thing about this is it is very easy to use different allocators on a
per-integer level. A practical example may be to use a faster stack-based
allocator for small temporaries, which can be bounded by some upper limit.</p>
<pre><code>// Allocate an integer on the heap
var heap_allocator = std.heap.c_allocator;
var a = try BigInt.init(heap_allocator);
defer a.deinit();

// ... and one on the stack
var stack_allocator = std.debug.global_allocator;
var b = try BigInt.init(stack_allocator);
defer b.deinit();

// ... and some in a shared arena with shared deallocation
var arena = ArenaAllocator.init(heap_allocator);
defer arena.deinit();

var c = try BigInt.init(&amp;arena.allocator);
var d = try BigInt.init(&amp;arena.allocator);
</code></pre>
<p>This isn’t possible in <a href="https://gmplib.org/">GMP</a>, which allows <a href="https://gmplib.org/manual/Custom-Allocation.html">specifying custom
allocation</a>
functions, but which are shared across the all objects. Only one
set of memory functions can be used per program.</p>
<h2>Handling OOM</h2>
<p>One issue with GMP is that out-of-memory conditions cannot easily be handled.
The only feasible way in-process way is to override the allocation functions and
use exceptions in C++, or longjmp back to a clean-up function which can attempt
to handle this as best as it can.</p>
<p>Since Zig was designed to handle allocation in a different way to C, we can
handle these much more easily. For any operation that could fail (either
out-of-memory or some other generic error), we can handle the error or pass it
back up the call-stack.</p>
<pre><code>var a = try BigInt.init(failing_allocator);
// maybe got an out-of-memory! if we did, lets pass it back to the caller
try a.set(0x123294781294871290478129478);
</code></pre>
<p>There is the small detriment that it is required to explicitly handle possible
failing functions (and for zig-bn, that is practically all of them). The
provided syntax makes this minimal boilerplate, and unlike GMP we
can at least see where something could go wrong and not have to rely on hidden
error control flow.</p>
<h2>Compile-time switch functions</h2>
<p>Zig provides a fair amount of compile-time support. A particular feature is the
ability to pass an arbitrary type <code>var</code> to a function. This gives a duck-typing
sort of feature and can provide more fluent interfaces than we otherwise could
write.</p>
<p>For example:</p>
<pre><code>pub fn plusOne(x: var) @typeOf(x) {
    const T = @typeOf(x);

    switch (@typeInfo(T)) {
        TypeId.Int =&gt; {
            return x + 1;
        },
        TypeId.Float =&gt; {
            return x + 1.0;
        },
        else =&gt; {
            @compileError(&quot;can't handle this type, sorry!&quot;);
        },
    }
}
</code></pre>
<p>This feature is used to combine <code>set</code> functions into a <a href="https://github.com/tiehuis/zig-bn/blob/8691da48134b029c26df5fd26ddf07b78b90bca3/bigint.zig#L104">single function</a>
instead of needing a variety of functions for each type as in GMP (<code>mpz_set_ui</code>,
<code>mpz_set_si</code>, …).</p>
<h2>Performance</h2>
<p>Perhaps the most important detail of a big integer library is its raw
performance. I’ll walk through the low-level addition routine and look at some
techniques we can use to speed it up incrementally.</p>
<p>The benchmarks used here can be found in this <a href="https://github.com/tiehuis/zig-bn/tree/8691da48134b029c26df5fd26ddf07b78b90bca3/bench">repository</a>.
We simply compute the 50000’th fibonacci number. This requires addition and
subtraction only.</p>
<p>Our initial naive implementation is as follows. It uses 32-bit limbs (so our
double-limb is a 64-bit integer) and simply propagates the carry. We force
inline the per-limb division and our debug asserts are compiled out in release
mode. Memory allocation is handled in the calling function.</p>
<pre><code>// a + b + *carry, sets carry to overflow bits
fn addLimbWithCarry(a: Limb, b: Limb, carry: &amp;Limb) Limb {
    const result = DoubleLimb(a) + DoubleLimb(b) + DoubleLimb(*carry);
    *carry = @truncate(Limb, result &gt;&gt; Limb.bit_count);
    return @truncate(Limb, result);
}

fn lladd(r: []Limb, a: []const Limb, b: []const Limb) void {
    debug.assert(a.len != 0 and b.len != 0);
    debug.assert(a.len &gt;= b.len);
    debug.assert(r.len &gt;= a.len + 1);

    var i: usize = 0;
    var carry: Limb = 0;

    while (i &lt; b.len) : (i += 1) {
        r[i] = @inlineCall(addLimbWithCarry, a[i], b[i], &amp;carry);
    }

    while (i &lt; a.len) : (i += 1) {
        r[i] = @inlineCall(addLimbWithCarry, a[i], 0, &amp;carry);
    }

    r[i] = carry;
}
</code></pre>
<p>The results are as follows:</p>
<pre><code>fib-zig: 0:00.75 real, 0.75 user, 0.00 sys
  debug: 0:06.61 real, 6.60 user, 0.00 sys
</code></pre>
<p>For comparison, the GMP run time is:</p>
<pre><code>fib-c:   0:00.17 real, 0.17 user, 0.00 sys
</code></pre>
<p>A more comparable C implementation (python) is:</p>
<pre><code>fib-py:  0:00.77 real, 0.77 user, 0.00 sys
</code></pre>
<p>A bit of work to do against GMP! We aren’t out of the ballpark compared
to less heavily optimized libraries. We are comparing the debug runtime version
as well since I consider it important that it runs reasonably quick for a good
development cycle, and not orders of magnitude slower.</p>
<h3>Leveraging Compiler Addition Builtins</h3>
<p>Zig provides a number of LLVM builtins to us. While these shouldn’t
usually be required, they can be valuable in certain cases. We’ll be using the
<a href="https://ziglang.org/documentation/master/#addWithOverflow"><code>@addWithOverflow</code></a>
builtin to perform addition while catching possible overflow.</p>
<p>Our new addition routine is now:</p>
<pre><code>fn lladd(r: []Limb, a: []const Limb, b: []const Limb) void {
    debug.assert(a.len != 0 and b.len != 0);
    debug.assert(a.len &gt;= b.len);
    debug.assert(r.len &gt;= a.len + 1);

    var i: usize = 0;
    var carry: Limb = 0;

    while (i &lt; b.len) : (i += 1) {
        var c: Limb = 0;
        c += Limb(@addWithOverflow(Limb, a[i], b[i], &amp;r[i]));
        c += Limb(@addWithOverflow(Limb, r[i], carry, &amp;r[i]));
        carry = c;
    }

    while (i &lt; a.len) : (i += 1) {
        carry = Limb(@addWithOverflow(Limb, a[i], carry, &amp;r[i]));
    }

    r[i] = carry;
}
</code></pre>
<p>The new results:</p>
<pre><code>fib-zig: 0:00.69 real, 0.69 user, 0.00 sys
  debug: 0:06.47 real, 6.42 user, 0.00 sys
</code></pre>
<p>A minimal, but noticeable improvement.</p>
<h3>Improving Debug Performance</h3>
<p>Debug mode in Zig performs runtime bounds checks which include array checks and other
checks for possible <a href="https://ziglang.org/documentation/master/#Undefined-Behavior">undefined behavior</a>.</p>
<p>For these inner loops this is a lot of overhead. Our assertions are sufficient
to cover all the looping cases. We can disable these safety checks on
a per-block basis:</p>
<pre><code>fn lladd(r: []Limb, a: []const Limb, b: []const Limb) void {
    @setRuntimeSafety(false);
    ...
}
</code></pre>
<pre><code>fib-zig: 0:00.69 real, 0.69 user, 0.00 sys
  debug: 0:03.91 real, 3.90 user, 0.00 sys
</code></pre>
<p>That is a lot better.</p>
<h3>64-bit limbs (and 128-bit integers).</h3>
<p>We have been using 32-bit words this entire time. Our machine word-size however
is 64-bits. Lets change our limb size only, and rerun our tests.</p>
<pre><code>fib-zig: 0:00.35 real, 0.35 user, 0.00 sys
  debug: 0:01.95 real, 1.95 user, 0.00 sys
</code></pre>
<p>Unsurprisingly, this is now twice as fast! It is fairly useful if your compiler
supports builtin 128-bit integer types when using 64-bit limbs. The reason is it
makes handling overflow in addition and especially multiplication much more
simple and easier to optimize by the compiler. Otherwise, <a href="https://github.com/v8/v8/blob/6.8.137/src/objects/bigint.cc#L2331">software
workarounds</a>
need to be done which can be much less performant.</p>
<h2>Implementation Performance Summary</h2>
<p>Benchmark code <a href="https://github.com/tiehuis/zig-bn/tree/master/bench">here</a>.</p>
<p>A performance comparison using the following libraries/languages:</p>
<ul>
<li><a href="https://github.com/tiehuis/zig-bn">zig-bn</a></li>
<li><a href="https://gmplib.org/">GMP</a></li>
<li><a href="https://golang.org/pkg/math/big/">Go</a></li>
<li><a href="https://github.com/python/cpython/blob/master/Objects/longobject.c">CPython</a></li>
<li><a href="https://github.com/rust-num/num-bigint">Rust-num</a></li>
</ul>
<p>Note that C and Go use assembly, while Rust/CPython both are implemented in Rust and C
respectively, and are comparable as non-tuned generic implementations.</p>
<h4>System Info</h4>
<pre><code>Architecture:        x86_64
Model name:          Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz
</code></pre>
<h4>Compiler Versions</h4>
<pre><code>zig:  0.2.0.ef3111be
gcc:  gcc (GCC) 8.1.0
go:   go version go1.10.2 linux/amd64
py:   Python 3.6.5
rust: rustc 1.25.0 (84203cac6 2018-03-25)
</code></pre>
<h3>Addition/Subtraction Test</h3>
<p>Computes the 50,000th fibonacci number.</p>
<pre><code>fib-zig: 0:00.35 real, 0.35 user, 0.00 sys
fib-c:   0:00.17 real, 0.17 user, 0.00 sys
fib-go:  0:00.20 real, 0.20 user, 0.00 sys
fib-py:  0:00.75 real, 0.75 user, 0.00 sys
fib-rs:  0:00.81 real, 0.81 user, 0.00 sys
</code></pre>
<h3>Multiplication/Addition Test</h3>
<p>Computes the 50,000th factorial.</p>
<p>Zig uses naive multiplication only while all others use asymptotically faster
algorithms such as <a href="https://en.wikipedia.org/wiki/Karatsuba_algorithm">karatsuba multiplication</a>.</p>
<pre><code>fac-zig: 0:00.54 real, 0.54 user, 0.00 sys
fac-c:   0:00.18 real, 0.18 user, 0.00 sys
fac-go:  0:00.21 real, 0.21 user, 0.00 sys
fac-py:  0:00.50 real, 0.48 user, 0.02 sys
fac-rs:  0:00.53 real, 0.53 user, 0.00 sys
</code></pre>
<h3>Division Test (single-limb)</h3>
<p>Computes the 20,000th factorial then divides it back down to 1.</p>
<p>Rust is most likely much slower since it <a href="https://github.com/rust-num/num-bigint/blob/master/src/algorithms.rs#L420">doesn’t special-case</a>
length 1 limbs.</p>
<pre><code>facdiv-zig: 0:00.99 real, 0.98 user, 0.00 sys
facdiv-c:   0:00.16 real, 0.16 user, 0.00 sys
facdiv-go:  0:00.93 real, 0.93 user, 0.00 sys
facdiv-py:  0:00.99 real, 0.99 user, 0.00 sys
facdiv-rs:  0:05.01 real, 4.98 user, 0.00 sys
</code></pre>
<h2>Summary</h2>
<p>In short, zig-bn has managed to get fairly good performance from a pretty simple
implementation. It is twice as fast as other generic libraries for the functions
we have optimized, and is likely to be similarly fast using comparable
algorithms for multiplication/division.</p>
<p>While I consider these good results for a very simple implementation (&lt;1k loc,
excluding tests) it is still lacking vs. GMP. Most notably, the algorithms used
are much more advanced and the gap would continue to grow as numbers grew even
larger. Hats off to the GMP project, as always.</p>
<p>A good start for a weeks work.</p>
    </div>
    <div class="footer">
      <a href="/">home</a> - <a href="https://github.com/tiehuis/">github</a> - <a href="/atom.xml">rss</a> <br/>
    </div>
  </body>
</html>
]]>  </content>
</entry>
</feed>
