mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-24 01:24:26 +01:00
lightningd: speed low-level json formatting.
Make json_start_member allocate extra space, which caller can directly print into, and also make caller call js_written_some() itself. MCP results from 5 runs, min-max(mean +/- stddev): store_load_msec:35071-36817(35617.2+/-7e+02) vsz_kb:2637488 store_rewrite_sec:35.790000-37.500000(36.6375+/-0.63) listnodes_sec:0.690000-0.780000(0.72+/-0.035) listchannels_sec:34.600000-36.340000(35.36+/-0.77) routing_sec:30.310000-30.730000(30.445+/-0.17) peer_write_all_sec:50.830000-52.750000(51.82+/-0.89) MCP notable changes from previous patch (>1 stddev): -listnodes_sec:0.720000-0.950000(0.86+/-0.077) +listnodes_sec:0.690000-0.780000(0.72+/-0.035) -listchannels_sec:40.300000-41.080000(40.668+/-0.29) +listchannels_sec:34.600000-36.340000(35.36+/-0.77) Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
neil saitug
parent
dc6d53e787
commit
20006b6553
@@ -94,14 +94,16 @@ static void adjust_io_write(struct io_conn *conn, ptrdiff_t delta)
|
|||||||
conn->plan[IO_OUT].arg.u1.cp += delta;
|
conn->plan[IO_OUT].arg.u1.cp += delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure js->outbuf has room for len */
|
/* Make sure js->outbuf has room for len: return pointer */
|
||||||
static void mkroom(struct json_stream *js, size_t len)
|
static char *mkroom(struct json_stream *js, size_t len)
|
||||||
{
|
{
|
||||||
ptrdiff_t delta = membuf_prepare_space(&js->outbuf, len);
|
ptrdiff_t delta = membuf_prepare_space(&js->outbuf, len);
|
||||||
|
|
||||||
/* If io_write is in progress, we shift it to point to new buffer pos */
|
/* If io_write is in progress, we shift it to point to new buffer pos */
|
||||||
if (js->reader)
|
if (js->reader)
|
||||||
adjust_io_write(js->reader, delta);
|
adjust_io_write(js->reader, delta);
|
||||||
|
|
||||||
|
return membuf_space(&js->outbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void js_written_some(struct json_stream *js)
|
static void js_written_some(struct json_stream *js)
|
||||||
@@ -140,8 +142,7 @@ static void json_stream_append_vfmt(struct json_stream *js,
|
|||||||
* membuf_num_space(&jcon->outbuf), the result was truncated! */
|
* membuf_num_space(&jcon->outbuf), the result was truncated! */
|
||||||
if (fmtlen >= membuf_num_space(&js->outbuf)) {
|
if (fmtlen >= membuf_num_space(&js->outbuf)) {
|
||||||
/* Make room for NUL terminator, even though we don't want it */
|
/* Make room for NUL terminator, even though we don't want it */
|
||||||
mkroom(js, fmtlen + 1);
|
vsprintf(mkroom(js, fmtlen + 1), fmt, ap2);
|
||||||
vsprintf(membuf_space(&js->outbuf), fmt, ap2);
|
|
||||||
}
|
}
|
||||||
membuf_added(&js->outbuf, fmtlen);
|
membuf_added(&js->outbuf, fmtlen);
|
||||||
js_written_some(js);
|
js_written_some(js);
|
||||||
@@ -175,16 +176,43 @@ static void check_fieldname(const struct json_stream *js,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void json_start_member(struct json_stream *js, const char *fieldname)
|
/* Caller must call js_written_some() if this returns non-NULL!
|
||||||
|
* Will never return NULL if extra is nonzero.
|
||||||
|
*/
|
||||||
|
static char *json_start_member(struct json_stream *js,
|
||||||
|
const char *fieldname, size_t extra)
|
||||||
{
|
{
|
||||||
|
char *dest;
|
||||||
|
|
||||||
/* Prepend comma if required. */
|
/* Prepend comma if required. */
|
||||||
if (!js->empty)
|
if (!js->empty)
|
||||||
json_stream_append(js, ",");
|
extra++;
|
||||||
|
|
||||||
check_fieldname(js, fieldname);
|
check_fieldname(js, fieldname);
|
||||||
if (fieldname)
|
if (fieldname)
|
||||||
json_stream_append_fmt(js, "\"%s\":", fieldname);
|
extra += 1 + strlen(fieldname) + 2;
|
||||||
|
|
||||||
|
if (!extra) {
|
||||||
|
dest = NULL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest = mkroom(js, extra);
|
||||||
|
|
||||||
|
if (!js->empty)
|
||||||
|
*(dest++) = ',';
|
||||||
|
if (fieldname) {
|
||||||
|
*(dest++) = '"';
|
||||||
|
memcpy(dest, fieldname, strlen(fieldname));
|
||||||
|
dest += strlen(fieldname);
|
||||||
|
*(dest++) = '"';
|
||||||
|
*(dest++) = ':';
|
||||||
|
}
|
||||||
|
membuf_added(&js->outbuf, extra);
|
||||||
|
|
||||||
|
out:
|
||||||
js->empty = false;
|
js->empty = false;
|
||||||
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void js_indent(struct json_stream *js, jsmntype_t type)
|
static void js_indent(struct json_stream *js, jsmntype_t type)
|
||||||
@@ -208,8 +236,8 @@ static void js_unindent(struct json_stream *js, jsmntype_t type)
|
|||||||
|
|
||||||
void json_array_start(struct json_stream *js, const char *fieldname)
|
void json_array_start(struct json_stream *js, const char *fieldname)
|
||||||
{
|
{
|
||||||
json_start_member(js, fieldname);
|
json_start_member(js, fieldname, 1)[0] = '[';
|
||||||
json_stream_append(js, "[");
|
js_written_some(js);
|
||||||
js_indent(js, JSMN_ARRAY);
|
js_indent(js, JSMN_ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,8 +249,8 @@ void json_array_end(struct json_stream *js)
|
|||||||
|
|
||||||
void json_object_start(struct json_stream *js, const char *fieldname)
|
void json_object_start(struct json_stream *js, const char *fieldname)
|
||||||
{
|
{
|
||||||
json_start_member(js, fieldname);
|
json_start_member(js, fieldname, 1)[0] = '{';
|
||||||
json_stream_append(js, "{");
|
js_written_some(js);
|
||||||
js_indent(js, JSMN_OBJECT);
|
js_indent(js, JSMN_OBJECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +266,7 @@ json_add_member(struct json_stream *js, const char *fieldname,
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
json_start_member(js, fieldname);
|
json_start_member(js, fieldname, 0);
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
json_stream_append_vfmt(js, fmt, ap);
|
json_stream_append_vfmt(js, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
@@ -251,9 +279,7 @@ void json_add_hex(struct json_stream *js, const char *fieldname,
|
|||||||
size_t hexlen = hex_str_size(len) - 1;
|
size_t hexlen = hex_str_size(len) - 1;
|
||||||
char *dest;
|
char *dest;
|
||||||
|
|
||||||
json_start_member(js, fieldname);
|
dest = json_start_member(js, fieldname, 1 + hexlen + 1);
|
||||||
mkroom(js, 1 + hexlen + 1);
|
|
||||||
dest = membuf_add(&js->outbuf, 1 + hexlen + 1);
|
|
||||||
dest[0] = '"';
|
dest[0] = '"';
|
||||||
if (!hex_encode(data, len, dest + 1, hexlen + 1))
|
if (!hex_encode(data, len, dest + 1, hexlen + 1))
|
||||||
abort();
|
abort();
|
||||||
|
|||||||
Reference in New Issue
Block a user