4 ms·
When I first saw this, I thought it ought to be possible to express the encoding/decoding in simple computations, but I only just got a chance to try things out
by nanis 5y ago
When I first saw this, I thought it ought to be possible to express the encoding/decoding in simple computations, but I only just got a chance to try things out[1].
There are many things I'd fiddle with in the original source. I noticed that since I first saw this post, someone even contributed an AVX2 implementation[2]. I stayed strictly in the standard C land:
This function converts a given character to the corresponding half-nibble (or dibit, don't really know what to call a pair of bits):
uint8_t
ws_to_half_nibble(uint8_t ws)
{
return ((ws >> 1) & 3) | (ws >> 4) | (ws >> 5);
}
Encoding a half-nibble to one of the four whitespace characters can be done using:
uint8_t
half_nibble_to_ws(uint8_t b)
{
const uint8_t b0 = b & 1;
const uint8_t b1 = b & 2;
return '\t' + b0 + 2 * b1 + 18 * (b0 & (b1 >> 1));
}
I haven't actually had a chance to investigate any performance gains, but this answers the question of whether we can replace the lookup tables with simple functions with no branching.
[1]: https://www.nu42.com/2021/10/another-optimization-tale.html https://www.nu42.com/2021/10/another-optimization-tale.html
[2]: https://news.ycombinator.com/item?id=28859061 https://news.ycombinator.com/item?id=28859061