Brad Fitzpatrick (bradfitz) wrote in lj_dev,
Brad Fitzpatrick

S1 in C

I rewrote S1 to be in two halves: generating a data structure with everything to be shown, and flattening it down based on their style (template) into the final result.

That by itself was minimal code... replacing fill_var_props() with a constructor for either an S1::Node or S1::NodeArray. Or a simple node which is just a scalar holding text, like $lastn_page{name} = LJ::ehtml($u->{name}.

Anyway, I then rewrote the flattening part 4 ways in Perl, and one way in C.

The 4 ways in Perl were:

-- via lots of regexps, like the old way.

-- with dynamically generated code blocks, one per template element

-- a mix of the two above, depending on if if the flattener was called recursively from a NodeArray's flattening. (generating the code block was expensive, so I figured it only made sense to do it if it was to be used more than once... being inside a NodeArray was the perfect heuristic)

-- Perl code that could be easily ported to C. (the prototype before I dived into C) This involved a first pass to calculate the total length. Whenever an attribute was used with a transform, the attribute had to be flattened first, if it wasn't a text node. Then that's cached away inside the node, so the second stage could use it. After the total length is calculate, a scalar buffer of that length is allocated (my $buf = "-" x $len) and the recursive stage begins, always taking $buf and a position into it to copy its node. It returns the position it ended at. Lots of paranoia about actual lengths not matching expected lengths from the previous stage.

Then the C way, as described above in the last Perl version.

The C version was the fastest, but only 7-9% faster than the old code. Not sure if it's worth it.

I had fun, though... I'd never written any Perl/C code before, and my code compiled and worked on its first run. It's definitely not as hard as I'd always expected.

The experimental version of is:

Attached to this bug about using C to make fast versions of hot functions:

It contains all the different variations. Search for "render_node", "gen_node_code", "node_length", "render_node_recurse", etc. That's the new stuff.

  • Post a new comment


    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded