v3: Use the aux struct as requested by Denys
v2: Add missing check on open
The performance and number of processes for a depmod -a with gzipped
modules was abysmal. This patch adds a fast path without fork for well-
behaved gzip files, benefiting all users of xmalloc_open_zipped_read_close.
modinfo radeon.ko.gz, a single-file reader, got 30% faster.
depmod -a, which used to fork over 800 times, got 20% faster. And of course
a whole lot less processes - much saved RAM.
function old new delta
inflate_unzip_internal 23042521+217
xmalloc_open_zipped_read_close73 201+128
unpack_gz_stream 567 570 +3
--
(add/remove: 0/0 grow/shrink: 3/0 up/down: 348/0) Total: 348 bytes
--
http://www.fastmail.com - Does exactly what it says on the tin
From 5ad6804ed4485eae176da45524ea848a00b11929 Mon Sep 17 00:00:00 2001
From: Lauri Kasanen cur...@operamail.com
Date: Sun, 30 Nov 2014 21:37:10 +0200
Subject: [PATCH] Add a gzip fastpath for the xmalloc readers, v3
v3: Use the aux struct as requested by Denys
v2: Add missing check on open
The performance and number of processes for a depmod -a with gzipped
modules was abysmal. This patch adds a fast path without fork for well-
behaved gzip files, benefiting all users of xmalloc_open_zipped_read_close.
modinfo radeon.ko.gz, a single-file reader, got 30% faster.
depmod -a, which used to fork over 800 times, got 20% faster. And of course
a whole lot less processes - much saved RAM.
function old new delta
inflate_unzip_internal 23042521+217
xmalloc_open_zipped_read_close73 201+128
unpack_gz_stream 567 570 +3
--
(add/remove: 0/0 grow/shrink: 3/0 up/down: 348/0) Total: 348 bytes
Signed-off-by: Lauri Kasanen cur...@operamail.com
---
archival/libarchive/decompress_gunzip.c | 38 -
archival/libarchive/open_transformer.c | 31 ++-
include/bb_archive.h| 2 ++
3 files changed, 65 insertions(+), 6 deletions(-)
diff --git a/archival/libarchive/decompress_gunzip.c
b/archival/libarchive/decompress_gunzip.c
index 7c6f38e..938d21f 100644
--- a/archival/libarchive/decompress_gunzip.c
+++ b/archival/libarchive/decompress_gunzip.c
@@ -971,10 +971,11 @@ static int inflate_get_next_window(STATE_PARAM_ONLY)
/* Called from unpack_gz_stream() and inflate_unzip() */
static IF_DESKTOP(long long) int
-inflate_unzip_internal(STATE_PARAM int in, int out)
+inflate_unzip_internal(STATE_PARAM transformer_aux_data_t *aux, int in, int
out)
{
IF_DESKTOP(long long) int n = 0;
ssize_t nwrote;
+ size_t bufsize = 0;
/* Allocate all global buffers (for DYN_ALLOC option) */
gunzip_window = xmalloc(GUNZIP_WSIZE);
@@ -1002,16 +1003,43 @@ inflate_unzip_internal(STATE_PARAM int in, int out)
while (1) {
int r = inflate_get_next_window(PASS_STATE_ONLY);
- nwrote = full_write(out, gunzip_window, gunzip_outbuf_count);
+
+ if (aux-mem_output_size) {
+ nwrote = gunzip_outbuf_count;
+ if (gunzip_outbuf_count + n bufsize) {
+ // increase by four blocks each time
+ const size_t newsize = bufsize + 4 *
gunzip_outbuf_count + 1;
+ aux-mem_output_buf =
xrealloc(aux-mem_output_buf, newsize);
+ bufsize = newsize;
+ }
+
+ if (bufsize aux-mem_output_size) {
+ free(aux-mem_output_buf);
+ aux-mem_output_buf = NULL;
+ n = -1;
+ goto ret;
+ }
+
+ memcpy(aux-mem_output_buf + n, gunzip_window,
gunzip_outbuf_count);
+ } else {
+ nwrote = full_write(out, gunzip_window,
gunzip_outbuf_count);
+ }
if (nwrote != (ssize_t)gunzip_outbuf_count) {
bb_perror_msg(write);
n = -1;
goto ret;
}
- IF_DESKTOP(n += nwrote;)
+ n += nwrote;
if (r == 0) break;
}
+ /* Final realloc, plus zero byte */
+ if (aux-mem_output_size) {
+ aux-mem_output_buf = xrealloc(aux-mem_output_buf, n + 1);
+ aux-mem_output_size = n;
+ aux-mem_output_buf[n] = '\0