commit 3c040f8374e0155983ffe86633b6050a16b13499
parent 54ebdaf31afea94fab7aad2224526e8a2d6cca05
Author: nsz <nszabolcs@gmail.com>
Date: Tue, 12 May 2009 00:29:33 +0200
decode_block optimization
Diffstat:
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;
+ }
}
}
}