From 5454ced7c8cfc2ba278c2635eecb9a5e4841e613 Mon Sep 17 00:00:00 2001 From: Nir Soffer Date: Fri, 5 Nov 2021 22:16:26 +0200 Subject: [PATCH] common/urils/vector.c: Optimize vector append Minimize reallocs by growing the backing array by factor of 1.5. Testing show that now append() is fast without calling reserve() upfront, simplifying code using vector. NBDKIT_BENCH=1 ./test-vector bench_reserve: 1000000 appends in 0.004496 s bench_append: 1000000 appends in 0.004180 s This can make a difference in code appending millions of items. Ported from libnbd commit 985dfa72ae2e41901f0af21e7205ef85428cd4bd. (cherry picked from commit 12356fa97a840de19bb61e0abedd6e7c7e578e5a) --- common/utils/vector.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/common/utils/vector.c b/common/utils/vector.c index 00cd2546..7df17e1b 100644 --- a/common/utils/vector.c +++ b/common/utils/vector.c @@ -41,11 +41,21 @@ int generic_vector_reserve (struct generic_vector *v, size_t n, size_t itemsize) { void *newptr; + size_t reqalloc, newalloc; - newptr = realloc (v->ptr, (n + v->alloc) * itemsize); + reqalloc = v->alloc + n; + if (reqalloc < v->alloc) + return -1; /* overflow */ + + newalloc = (v->alloc * 3 + 1) / 2; + + if (newalloc < reqalloc) + newalloc = reqalloc; + + newptr = realloc (v->ptr, newalloc * itemsize); if (newptr == NULL) return -1; v->ptr = newptr; - v->alloc += n; + v->alloc = newalloc; return 0; } -- 2.31.1