From 8ad21e6b59e5e5a3104660f17ad2b0e9122edecf Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Wed, 15 Feb 2017 15:14:12 +0100 Subject: xplist: Improve writing of large PLIST_DATA nodes by growing buffer in advance Instead of letting the buffer grow by just the amount of bytes currently transformed to base64 - which is basically line by line - we now calculate the size of the output blob in advance and grow the buffer accordingly. This will reduce the amount of reallocs to just one, which is especially important for large data blobs. While this is a general improvement for all platforms, it is on platforms like Windows where realloc() can be REALLY slow; converting a 20mb blob to XML can easily take up to a minute (due to the several hundred thousand calls to realloc()). With this commit, it will be fast again. --- src/bytearray.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/bytearray.c') diff --git a/src/bytearray.c b/src/bytearray.c index 861890e..fff5089 100644 --- a/src/bytearray.c +++ b/src/bytearray.c @@ -41,15 +41,20 @@ void byte_array_free(bytearray_t *ba) free(ba); } +void byte_array_grow(bytearray_t *ba, size_t amount) +{ + size_t increase = (amount > PAGE_SIZE) ? (amount+(PAGE_SIZE-1)) & (~(PAGE_SIZE-1)) : PAGE_SIZE; + ba->data = realloc(ba->data, ba->capacity + increase); + ba->capacity += increase; +} + void byte_array_append(bytearray_t *ba, void *buf, size_t len) { if (!ba || !ba->data || (len <= 0)) return; size_t remaining = ba->capacity-ba->len; if (len > remaining) { size_t needed = len - remaining; - size_t increase = (needed > PAGE_SIZE) ? (needed+(PAGE_SIZE-1)) & (~(PAGE_SIZE-1)) : PAGE_SIZE; - ba->data = realloc(ba->data, ba->capacity + increase); - ba->capacity += increase; + byte_array_grow(ba, needed); } memcpy(((char*)ba->data) + ba->len, buf, len); ba->len += len; -- cgit v1.1-32-gdbae