[ovs-dev] [PATCH v3 1/1] json: Use reference counting in JSON objects
Rodriguez Betancourt, Esteban
estebarb at hpe.com
Tue Oct 4 19:31:48 UTC 2016
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 <estebarb at 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
More information about the dev
mailing list