Browse Source

Improve json_object -> string performance

Removes variadic prints for ~3x performance improvement.
tags/json-c-0.13-20171207
Quentin Young 8 years ago
parent
commit
9ff0f4987f
5 changed files with 19 additions and 82 deletions
  1. +11
    -4
      json_object.c
  2. +6
    -28
      printbuf.c
  3. +1
    -1
      printbuf.h
  4. +1
    -39
      tests/test_printbuf.c
  5. +0
    -10
      tests/test_printbuf.expected

+ 11
- 4
json_object.c View File

@@ -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)


+ 6
- 28
printbuf.c View File

@@ -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));
}

+ 1
- 1
printbuf.h View File

@@ -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);


+ 1
- 39
tests/test_printbuf.c View File

@@ -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;
}

+ 0
- 10
tests/test_printbuf.expected View File

@@ -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
========================================

Loading…
Cancel
Save