flate

deflate implementation
git clone git://git.suckless.org/flate
Log | Files | Refs | README

commit 3c040f8374e0155983ffe86633b6050a16b13499
parent 54ebdaf31afea94fab7aad2224526e8a2d6cca05
Author: nsz <nszabolcs@gmail.com>
Date:   Tue, 12 May 2009 00:29:33 +0200

decode_block optimization
Diffstat:
Makefile | 2+-
inflate.c | 40++++++++++++++++++++++++++++------------
2 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/Makefile b/Makefile @@ -18,7 +18,7 @@ clean: gcov: inflate.c gcc -fprofile-arcs -ftest-coverage -pg -g -Wall $< - cat b.dat | ./a.out > /dev/null + cat d.dat | ./a.out > /dev/null gcov -b $< > /dev/null gprof a.out > $<.gprof gcc -g -Wall $< diff --git a/inflate.c b/inflate.c @@ -1,10 +1,3 @@ -/* -TODO: - check int types - better io model - better error handling -*/ - #include <stdlib.h> #include <string.h> @@ -414,13 +407,36 @@ static void decode_block(Stream *s, Huff *lhuff, Huff *dhuff) { dist = distbase[sym] + getbits(s, distbits[sym]); if (s->error != FlateOk) return; - /* copy match */ - /* TODO: unroll 3-4 loops */ - for (i = 0; i < len; i++) { - s->win[s->pos] = s->win[(s->pos - dist) & 0x7ff]; - s->pos++; + /* copy match, loop unroll for common case */ + if (s->pos + len <= WinSize) { + uint pos = s->pos; + + while (len > 4) { + s->win[pos] = s->win[(pos - dist) & 0x7ff]; + pos++; + s->win[pos] = s->win[(pos - dist) & 0x7ff]; + pos++; + s->win[pos] = s->win[(pos - dist) & 0x7ff]; + pos++; + s->win[pos] = s->win[(pos - dist) & 0x7ff]; + pos++; + len -= 4; + } + while (len > 0) { + s->win[pos] = s->win[(pos - dist) & 0x7ff]; + pos++; + len--; + } + s->pos = pos; if (!checkpos(s)) return; + } else { + for (i = 0; i < len; i++) { + s->win[s->pos] = s->win[(s->pos - dist) & 0x7ff]; + s->pos++; + if (!checkpos(s)) + return; + } } } }