Browse Source

libplugin: don't parse partial JSON repeatedly.

Tested on a test node which had made 50,000 payment, with no optimization.

For comparison, time for 'listsendpays' was 0.983s.

time lightning-cli -R --network=regtest --lightning-dir /tmp/ltests-k8jhvtty/test_pay_stress_1/lightning-1/ listpays > /dev/null

Before:
	real	0m52.415s
	user	0m0.127s
	sys	0m0.044s

After:
	real	0m42.741s
	user	0m0.149s
	sys	0m0.016s

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: libplugin: significant speedups for reading large JSON replies (e.g. calling listsendpays on large nodes, or listchannels / listnodes).
bump-pyln-proto
Rusty Russell 4 years ago
parent
commit
40f17d994c
  1. 16
      plugins/libplugin.c

16
plugins/libplugin.c

@ -651,9 +651,11 @@ static bool rpc_read_response_one(struct plugin *plugin)
bool valid;
const jsmntok_t *toks, *jrtok;
/* FIXME: This could be done more efficiently by storing the
* toks and doing an incremental parse, like lightning-cli
* does. */
/* For our convenience, lightningd always ends JSON requests with
* \n\n. We can abuse that as an optimization here.*/
if (!memmem(plugin->rpc_buffer, plugin->rpc_used, "\n\n", 2))
return false;
toks = json_parse_input(NULL, plugin->rpc_buffer, plugin->rpc_used,
&valid);
if (!toks) {
@ -681,10 +683,10 @@ static bool rpc_read_response_one(struct plugin *plugin)
handle_rpc_reply(plugin, toks);
/* Move this object out of the buffer */
memmove(plugin->rpc_buffer, plugin->rpc_buffer + toks[0].end,
tal_count(plugin->rpc_buffer) - toks[0].end);
plugin->rpc_used -= toks[0].end;
/* Move this object out of the buffer (+ 2 for \n\n)*/
memmove(plugin->rpc_buffer, plugin->rpc_buffer + toks[0].end + 2,
tal_count(plugin->rpc_buffer) - toks[0].end - 2);
plugin->rpc_used -= toks[0].end + 2;
tal_free(toks);
return true;

Loading…
Cancel
Save