From 142f411b1305d4c9857532f66e61a895604160a9 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 16 Apr 2012 00:25:46 +0200 Subject: Improve string escape performance a little Instead of escaping a string, returning a new one and running strlen() on that, use an output variable to store the length, since we can easily calculate that during the escape process anyway. This should shave off a tiny bit of CPU time. Signed-off-by: Gergely Nagy --- lib/buffer.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'lib/buffer.c') diff --git a/lib/buffer.c b/lib/buffer.c index 8bdb3ef..3d92224 100644 --- a/lib/buffer.c +++ b/lib/buffer.c @@ -55,7 +55,7 @@ static const unsigned char json_exceptions[] = }; static inline char * -_ul_str_escape (const char *str) +_ul_str_escape (const char *str, size_t *length) { const unsigned char *p; char *dest; @@ -139,6 +139,8 @@ _ul_str_escape (const char *str) } *q = 0; + if (length) + *length = q - dest; return dest; } @@ -170,19 +172,16 @@ ul_buffer_append (ul_buffer_t *buffer, const char *key, const char *value) char *k, *v; size_t lk, lv; - k = _ul_str_escape (key); + k = _ul_str_escape (key, &lk); if (!k) return NULL; - v = _ul_str_escape (value); + v = _ul_str_escape (value, &lv); if (!v) { free (k); return NULL; } - lk = strlen (k); - lv = strlen (v); - buffer = _ul_buffer_ensure_size (buffer, buffer->len + lk + lv + 6); if (!buffer) { -- cgit From 4fd758dcde350fda5e87573d9c7004a35b136741 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sun, 29 Apr 2012 11:12:39 +0200 Subject: Reduce the number of memory allocations Make the string escape use an ul_buffer_t, to avoid unnecessary memory allocations. This greatly reduces the number of mallocs made, and thus results in a noticable increase in speed. Signed-off-by: Gergely Nagy --- lib/buffer.c | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) (limited to 'lib/buffer.c') diff --git a/lib/buffer.c b/lib/buffer.c index 3d92224..ef448bf 100644 --- a/lib/buffer.c +++ b/lib/buffer.c @@ -54,11 +54,20 @@ static const unsigned char json_exceptions[] = 0xff, '\0' }; +static __thread ul_buffer_t escape_buffer; + +static void ul_buffer_finish (void) __attribute__((destructor)); + +static void +ul_buffer_finish (void) +{ + free (escape_buffer.msg); +} + static inline char * -_ul_str_escape (const char *str, size_t *length) +_ul_str_escape (const char *str, char *dest, size_t *length) { const unsigned char *p; - char *dest; char *q; static unsigned char exmap[256]; static int exmap_inited; @@ -67,7 +76,7 @@ _ul_str_escape (const char *str, size_t *length) return NULL; p = (unsigned char *)str; - q = dest = malloc (strlen (str) * 6 + 1); + q = dest; if (!exmap_inited) { @@ -171,35 +180,44 @@ ul_buffer_append (ul_buffer_t *buffer, const char *key, const char *value) { char *k, *v; size_t lk, lv; + size_t orig_len = buffer->len; - k = _ul_str_escape (key, &lk); + /* Append the key to the buffer */ + escape_buffer.len = 0; + _ul_buffer_ensure_size (&escape_buffer, strlen (key) * 6 + 1); + k = _ul_str_escape (key, escape_buffer.msg, &lk); if (!k) return NULL; - v = _ul_str_escape (value, &lv); + + buffer = _ul_buffer_ensure_size (buffer, buffer->len + lk + 4); + if (!buffer) + return NULL; + + memcpy (buffer->msg + buffer->len, "\"", 1); + memcpy (buffer->msg + buffer->len + 1, k, lk); + memcpy (buffer->msg + buffer->len + 1 + lk, "\":\"", 3); + + /* Append the value to the buffer */ + escape_buffer.len = 0; + _ul_buffer_ensure_size (&escape_buffer, strlen (value) * 6 + 1); + v = _ul_str_escape (value, escape_buffer.msg, &lv); if (!v) { - free (k); + buffer->len = orig_len; return NULL; } buffer = _ul_buffer_ensure_size (buffer, buffer->len + lk + lv + 6); if (!buffer) { - free (k); - free (v); + buffer->len = orig_len; return NULL; } - memcpy (buffer->msg + buffer->len, "\"", 1); - memcpy (buffer->msg + buffer->len + 1, k, lk); - memcpy (buffer->msg + buffer->len + 1 + lk, "\":\"", 3); memcpy (buffer->msg + buffer->len + 1 + lk + 3, v, lv); memcpy (buffer->msg + buffer->len + 1 + lk + 3 + lv, "\",", 2); buffer->len += lk + lv + 6; - free (k); - free (v); - return buffer; } -- cgit