[PATCH 2/2] (g)unzip: Optimize inflate_codes()

Joakim Tjernlund Joakim.Tjernlund at transmode.se
Mon Feb 8 17:55:16 UTC 2010


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.

Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund at transmode.se>
---
 archival/libunarchive/decompress_unzip.c |   47 ++++++++++++++++++++++++++++-
 1 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/archival/libunarchive/decompress_unzip.c b/archival/libunarchive/decompress_unzip.c
index c616202..fe10657 100644
--- a/archival/libunarchive/decompress_unzip.c
+++ b/archival/libunarchive/decompress_unzip.c
@@ -589,11 +589,54 @@ 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 (e < 3)
+						fprintf(stderr, "error len:%d\n", e);
+					if (w & 1) {
+						gunzip_window[w++] = gunzip_window[dd++];
+						--e;
+					}
+
+					sout = (unsigned short *) (gunzip_window + w);
+					if (delta > 2) {
+						unsigned short *sfrom;
+
+						sfrom = (unsigned short *) (gunzip_window + dd);
+						loops = e >> 1;
+						w += loops*2;
+						dd += loops*2;
+						do
+							move_from_unaligned16(*sout++, sfrom++);
+						while (--loops);
+					} else {
+						unsigned short pat16;
+
+						pat16 = *(sout-1);
+						if (delta == 1) {
+							//union uu mm;
+							/* copy one char pattern to both bytes */
+							mm.us = pat16;
+							mm.b[0] = mm.b[1];
+							pat16 = mm.us;
+						}
+						loops = e >> 1;
+						w += loops*2;
+						dd += loops*2;
+						do
+							*sout++ = pat16;
+						while (--loops);
+					}
+					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