summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2014-03-24 09:38:33 +0100
committerantirez <antirez@gmail.com>2014-03-24 09:44:11 +0100
commita9caca0424197e1b43cc98c5106cca5c86e3ac34 (patch)
treef1a780fc94019deec824e9ed7f8f3d9b9161c542
parent6972f18cbd1b71ebaf4a8f077ab79a59ccaccea2 (diff)
downloadredis-a9caca0424197e1b43cc98c5106cca5c86e3ac34.tar.gz
sdscatvprintf(): guess buflen using format length.
sdscatvprintf() uses a loop where it tries to output the formatted string in a buffer of the initial length, if there was not enough room, a buffer of doubled size is tried and so forth. The initial guess for the buffer length was very poor, an hardcoded "16". This caused the printf to be processed multiple times without a good reason. Given that printf functions are already not fast, the overhead was significant. The new heuristic is to use a buffer 4 times the length of the format buffer, and 32 as minimal size. This appears to be a good balance for typical uses of the function inside the Redis code base. This change improved INFO command performances 3 times.
-rw-r--r--src/sds.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/src/sds.c b/src/sds.c
index 64c9a9615..ef0bb6bf9 100644
--- a/src/sds.c
+++ b/src/sds.c
@@ -293,8 +293,9 @@ sds sdscpy(sds s, const char *t) {
sds sdscatvprintf(sds s, const char *fmt, va_list ap) {
va_list cpy;
char *buf, *t;
- size_t buflen = 16;
+ size_t buflen = strlen(fmt)*4;
+ if (buflen < 32) buflen = 32;
while(1) {
buf = zmalloc(buflen);
if (buf == NULL) return NULL;