From: Quentin Young Date: Thu, 2 Feb 2017 17:16:26 +0000 (+0000) Subject: Improve json_object -> string performance X-Git-Tag: json-c-0.13-20171207~104^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9ff0f4987fc17f957f520623f8dcc811fe9ffd22;p=thirdparty%2Fjson-c.git Improve json_object -> string performance Removes variadic prints for ~3x performance improvement. --- diff --git a/json_object.c b/json_object.c index 139d8578..2d688cea 100644 --- a/json_object.c +++ b/json_object.c @@ -147,9 +147,13 @@ static int json_escape_str(struct printbuf *pb, const char *str, int len, int fl printbuf_memappend(pb, str + start_offset, pos - start_offset); - sprintbuf(pb, "\\u00%c%c", - json_hex_chars[c >> 4], - json_hex_chars[c & 0xf]); + static char sbuf[7]; + snprintf(sbuf, sizeof(sbuf), + "\\u00%c%c", + json_hex_chars[c >> 4], + json_hex_chars[c & 0xf]); + printbuf_memappend (pb, sbuf, sizeof(sbuf) - 1); + start_offset = ++pos; } else pos++; @@ -585,7 +589,10 @@ static int json_object_int_to_json_string(struct json_object* jso, int level, int flags) { - return sprintbuf(pb, "%" PRId64, jso->o.c_int64); + /* room for 19 digits, the sign char, and a null term */ + static char sbuf[21]; + snprintf(sbuf, sizeof(sbuf), "%"PRId64, jso->o.c_int64); + return sprintbuf(pb, sbuf); } struct json_object* json_object_new_int(int32_t i) diff --git a/printbuf.c b/printbuf.c index 2745339c..2d52ddd5 100644 --- a/printbuf.c +++ b/printbuf.c @@ -85,6 +85,7 @@ int printbuf_memappend(struct printbuf *p, const char *buf, int size) if (printbuf_extend(p, p->bpos + size + 1) < 0) return -1; } + memcpy(p->buf + p->bpos, buf, size); p->bpos += size; p->buf[p->bpos]= '\0'; @@ -111,34 +112,6 @@ int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len) return 0; } -int sprintbuf(struct printbuf *p, const char *msg, ...) -{ - va_list ap; - char *t; - int size; - char buf[128]; - - /* user stack buffer first */ - va_start(ap, msg); - size = vsnprintf(buf, 128, msg, ap); - va_end(ap); - /* if string is greater than stack buffer, then use dynamic string - with vasprintf. Note: some implementation of vsnprintf return -1 - if output is truncated whereas some return the number of bytes that - would have been written - this code handles both cases. */ - if(size == -1 || size > 127) { - va_start(ap, msg); - if((size = vasprintf(&t, msg, ap)) < 0) { va_end(ap); return -1; } - va_end(ap); - printbuf_memappend(p, t, size); - free(t); - return size; - } else { - printbuf_memappend(p, buf, size); - return size; - } -} - void printbuf_reset(struct printbuf *p) { p->buf[0] = '\0'; @@ -152,3 +125,8 @@ void printbuf_free(struct printbuf *p) free(p); } } + +inline int sprintbuf(struct printbuf *p, const char *buf) +{ + return printbuf_memappend(p, buf, strlen(buf)); +} diff --git a/printbuf.h b/printbuf.h index b1bde7f9..d8c24385 100644 --- a/printbuf.h +++ b/printbuf.h @@ -62,7 +62,7 @@ extern int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len); extern int -sprintbuf(struct printbuf *p, const char *msg, ...); +sprintbuf(struct printbuf *p, const char *msg); extern void printbuf_reset(struct printbuf *p); diff --git a/tests/test_printbuf.c b/tests/test_printbuf.c index c8b8ad03..143ff4a6 100644 --- a/tests/test_printbuf.c +++ b/tests/test_printbuf.c @@ -17,7 +17,7 @@ static void test_basic_printbuf_memset() printf("%s: starting test\n", __func__); pb = printbuf_new(); - sprintbuf(pb, "blue:%d", 1); + sprintbuf(pb, "blue:1"); printbuf_memset(pb, -1, 'x', 52); printf("Buffer contents:%.*s\n", printbuf_length(pb), pb->buf); printbuf_free(pb); @@ -111,42 +111,6 @@ static void test_printbuf_memappend(int *before_resize) printf("%s: end test\n", __func__); } -static void test_sprintbuf(int before_resize); -static void test_sprintbuf(int before_resize) -{ - struct printbuf *pb; - - printf("%s: starting test\n", __func__); - pb = printbuf_new(); - printf("Buffer length: %d\n", printbuf_length(pb)); - - char *data = malloc(before_resize + 1 + 1); - memset(data, 'X', before_resize + 1 + 1); - data[before_resize + 1] = '\0'; - sprintbuf(pb, "%s", data); - free(data); - printf("sprintbuf to just after resize(%d+1): %d, [%s], strlen(buf)=%d\n", before_resize, printbuf_length(pb), pb->buf, (int)strlen(pb->buf)); - - printbuf_reset(pb); - sprintbuf(pb, "plain"); - printf("%d, [%s]\n", printbuf_length(pb), pb->buf); - - sprintbuf(pb, "%d", 1); - printf("%d, [%s]\n", printbuf_length(pb), pb->buf); - - sprintbuf(pb, "%d", INT_MAX); - printf("%d, [%s]\n", printbuf_length(pb), pb->buf); - - sprintbuf(pb, "%d", INT_MIN); - printf("%d, [%s]\n", printbuf_length(pb), pb->buf); - - sprintbuf(pb, "%s", "%s"); - printf("%d, [%s]\n", printbuf_length(pb), pb->buf); - - printbuf_free(pb); - printf("%s: end test\n", __func__); -} - int main(int argc, char **argv) { int before_resize = 0; @@ -159,8 +123,6 @@ int main(int argc, char **argv) printf("========================================\n"); test_printbuf_memappend(&before_resize); printf("========================================\n"); - test_sprintbuf(before_resize); - printf("========================================\n"); return 0; } diff --git a/tests/test_printbuf.expected b/tests/test_printbuf.expected index 142db0ba..a3b107d7 100644 --- a/tests/test_printbuf.expected +++ b/tests/test_printbuf.expected @@ -20,13 +20,3 @@ Append to just before resize: 31, [XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX] Append to just after resize: 32, [XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX] test_printbuf_memappend: end test ======================================== -test_sprintbuf: starting test -Buffer length: 0 -sprintbuf to just after resize(31+1): 32, [XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX], strlen(buf)=32 -5, [plain] -6, [plain1] -16, [plain12147483647] -27, [plain12147483647-2147483648] -29, [plain12147483647-2147483648%s] -test_sprintbuf: end test -========================================