[PATCH 2/2] (g)unzip: Optimize inflate_codes()
Joakim Tjernlund
joakim.tjernlund at transmode.se
Thu Feb 11 07:42:31 UTC 2010
Denys Vlasenko <vda.linux at googlemail.com> wrote on 2010/02/11 03:24:19:
>
> On Wednesday 10 February 2010 08:34, Joakim Tjernlund wrote:
> > > > > Left some debug in, the correct bloatcheck is:
> > > > > function old new delta
> > > > > inflate_codes 624 791 +167
> > > > > -------------------------------------------------------------------------
> > > > >----- (add/remove: 0/0 grow/shrink: 1/0 up/down: 167/0) Total:
> > > > > 167 bytes text data bss dec hex filename
> > > > > 705967 2137 9072 717176 af178 busybox_old
> > > > > 706134 2137 9072 717343 af21f busybox_unstripped
> > > >
> > > > And yet some:
> > > > function old new delta
> > > > inflate_codes 624 728 +104
> > > > ---------------------------------------------------------------------------
> > > >--- (add/remove: 0/0 grow/shrink: 1/0 up/down: 104/0) Total: 104
> > > > bytes text data bss dec hex filename
> > > > 705967 2137 9072 717176 af178 busybox_old
> > > > 706071 2137 9072 717280 af1e0 busybox_unstripped
>
> Great. But looks like you forgot to send the patch without this debug.
> The only patch I found has this:
>
> + /* Align out addr */
> + if (e < 3)
> + fprintf(stderr, "error len:%d\n", e);
Hehe, here we go then. Looking at the gzip code I think it is crap though.
The upstream gzip code is old and unoptimized. One should just scrap
it and redo it with zlib instead.
Jocke
>From cb65f50ec0599ec40677b655149491a2918133bc Mon Sep 17 00:00:00 2001
From: Joakim Tjernlund <Joakim.Tjernlund at transmode.se>
Date: Mon, 8 Feb 2010 18:46:38 +0100
Subject: [PATCH] (g)unzip: Optimize inflate_codes()
Ported the recent optimization from the Linux kernel.
This will not perform as god as the kernel version as the
code structure in busybox is different and I had to adopt
the optimization to it.
This has seen very little testing and is a RFC only at this point.
The inflate speed increase in the kernel was 12-15% on ppc.
---
V2: Optimize size a bit:
function old new delta
inflate_codes 624 735 +111
archival/libunarchive/decompress_unzip.c | 42 ++++++++++++++++++++++++++++-
1 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/archival/libunarchive/decompress_unzip.c b/archival/libunarchive/decompress_unzip.c
index c616202..111d7fc 100644
--- a/archival/libunarchive/decompress_unzip.c
+++ b/archival/libunarchive/decompress_unzip.c
@@ -589,11 +589,49 @@ static NOINLINE int inflate_codes(STATE_PARAM_ONLY)
w += e;
dd += e;
} else {
+ unsigned short *sout;
+ unsigned int loops;
+ union uu {
+ unsigned short us;
+ unsigned char b[2];
+ } mm;
/* do it slow to avoid memcpy() overlap */
/* !NOMEMCPY */
- do {
+ /* minimum length is three */
+ /* Align out addr */
+ if (w & 1) {
+ gunzip_window[w++] = gunzip_window[dd++];
+ --e;
+ }
+ /* Use pre increment as it is faster on some arch's */
+ sout = (unsigned short *) (gunzip_window + w - 2);
+ if (delta > 2) {
+ unsigned short *sfrom;
+
+ sfrom = (unsigned short *) (gunzip_window + dd - 2);
+ loops = e >> 1;
+ do
+ move_from_unaligned16(*++sout, ++sfrom);
+ while (--loops);
+ } else {
+ unsigned short pat16;
+
+ pat16 = *sout;
+ if (delta == 1) {
+ /* copy one char pattern to both bytes */
+ mm.us = pat16;
+ mm.b[0] = mm.b[1];
+ pat16 = mm.us;
+ }
+ loops = e >> 1;
+ do
+ *++sout = pat16;
+ while (--loops);
+ }
+ w += e & ~1;
+ dd += e & ~1;
+ if (e & 1)
gunzip_window[w++] = gunzip_window[dd++];
- } while (--e);
}
if (w == GUNZIP_WSIZE) {
gunzip_outbuf_count = w;
--
1.6.4.4
More information about the busybox
mailing list