diff options
author | Gergely Nagy <algernon@madhouse-project.org> | 2012-04-29 11:12:39 +0200 |
---|---|---|
committer | Gergely Nagy <algernon@madhouse-project.org> | 2012-04-29 11:19:06 +0200 |
commit | 4fd758dcde350fda5e87573d9c7004a35b136741 (patch) | |
tree | d599260e49788d159135d37fbc6afea431bb2e3c /lib/buffer.c | |
parent | 7dc0d11639d5f9fd2c4d0e01ab12813a5898f596 (diff) | |
download | libumberlog-4fd758dcde350fda5e87573d9c7004a35b136741.tar.gz libumberlog-4fd758dcde350fda5e87573d9c7004a35b136741.tar.xz libumberlog-4fd758dcde350fda5e87573d9c7004a35b136741.zip |
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 <algernon@madhouse-project.org>
Diffstat (limited to 'lib/buffer.c')
-rw-r--r-- | lib/buffer.c | 46 |
1 files changed, 32 insertions, 14 deletions
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; } |