After profiling OVSDB insert performance it was found that some significant portion of its time OVSDB is calling the function json_clone.
Also, the current usages of json_clone never modify the json, just keeps it to prevent it to be freed. With that in mind the struct json, json_create, json_clone and json_destroy were modified to keep a count of how many references of the json struct are left. Only when that count reaches zero the json struct is freed. The old "json_clone" function was renamed as "json_deep_clone". Some examples of the performance difference: In these tests a test table with 4 columns (string, string, bool, integer) was used. All the tests used "commit block". *** 50 process each inserting 1000 rows *** Master OVS Test Duration 131 seconds Average Inserts Per second 746.2687 inserts/s Average Insert Duration 134.1382 ms Minimal Insert Duration 0.166202 ms Maximum Insert Duration 489.8593 ms JSON GC Patch Test Duration 86 seconds Average Inserts Per second 1176 inserts/s Average Insert Duration 82.26761 ms Minimal Insert Duration 0.165448 ms Maximum Insert Duration 751.2111 ms *** 5 process each inserting 10000 rows *** Master OVS Test Duration 8 seconds Average Inserts Per second 7142.857 inserts/s Average Insert Duration 0.656431 ms Minimal Insert Duration 0.125197 ms Maximum Insert Duration 11.93203 ms JSON GC Patch Test Duration 7 seconds Average Inserts Per second 8333.333 inserts/s Average Insert Duration 0.55688 ms Minimal Insert Duration 0.143233 ms Maximum Insert Duration 26.26319 ms Signed-off-by: Esteban Rodriguez Betancourt <esteb...@hpe.com> --- include/openvswitch/json.h | 2 ++ lib/json.c | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/openvswitch/json.h b/include/openvswitch/json.h index 13f346c..83775ed 100644 --- a/include/openvswitch/json.h +++ b/include/openvswitch/json.h @@ -63,6 +63,7 @@ struct json_array { /* A JSON value. */ struct json { enum json_type type; + size_t count; union { struct shash *object; /* Contains "struct json *"s. */ struct json_array array; @@ -99,6 +100,7 @@ bool json_boolean(const struct json *); double json_real(const struct json *); int64_t json_integer(const struct json *); +struct json *json_deep_clone(const struct json *); struct json *json_clone(const struct json *); void json_destroy(struct json *); diff --git a/lib/json.c b/lib/json.c index 995f3c2..7b0398a 100644 --- a/lib/json.c +++ b/lib/json.c @@ -333,7 +333,7 @@ static void json_destroy_array(struct json_array *array); void json_destroy(struct json *json) { - if (json) { + if (json && !--json->count) { switch (json->type) { case JSON_OBJECT: json_destroy_object(json->u.object); @@ -392,7 +392,7 @@ static struct json *json_clone_array(const struct json_array *array); /* Returns a deep copy of 'json'. */ struct json * -json_clone(const struct json *json) +json_deep_clone(const struct json *json) { switch (json->type) { case JSON_OBJECT: @@ -421,6 +421,15 @@ json_clone(const struct json *json) } } +/* Returns 'json', with the reference count incremented. */ +struct json * +json_clone(const struct json *json_) +{ + struct json *json = CONST_CAST(struct json *, json_); + json->count++; + return json; +} + static struct json * json_clone_object(const struct shash *object) { @@ -547,6 +556,10 @@ json_equal_array(const struct json_array *a, const struct json_array *b) bool json_equal(const struct json *a, const struct json *b) { + if (a == b) { + return true; + } + if (a->type != b->type) { return false; } @@ -1405,6 +1418,7 @@ json_create(enum json_type type) { struct json *json = xmalloc(sizeof *json); json->type = type; + json->count = 1; return json; } -- 2.7.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev