Improve performance of vm_image_to_json

Use a callback-based function to create the heap JSON array. This avoids
the O(n) insertion time of cJSON_AddItemToArray.
This commit is contained in:
Nunuhara Cabbage
2022-06-25 10:00:24 -07:00
parent 3a40542aab
commit 9f42ee379d
3 changed files with 57 additions and 20 deletions
+1
View File
@@ -210,6 +210,7 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
/* These utilities create an Array of count items.
* The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
CJSON_PUBLIC(cJSON *) cJSON_CreateArray_cb(int count, cJSON *(*get_item)(int,void*), void *data);
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray_cb(int count, int (*get_number)(int,void*), void *data);
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
+36
View File
@@ -2488,6 +2488,42 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray_cb(int count, int (*get_number)(int,v
return a;
}
/* XXX: xsystem4 addition: callback-based CreateArray. */
CJSON_PUBLIC(cJSON *) cJSON_CreateArray_cb(int count, cJSON *(*get_item)(int,void*), void *data)
{
size_t i = 0;
cJSON *n = NULL;
cJSON *p = NULL;
cJSON *a = NULL;
if (count < 0)
{
return NULL;
}
a = cJSON_CreateArray();
for(i = 0; a && (i < (size_t)count); i++)
{
n = get_item(i, data);;
if (!n)
{
// XXX: NULL return is ignored
continue;
}
if(!i)
{
a->child = n;
}
else
{
suffix_object(p, n);
}
p = n;
}
return a;
}
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count)
{
size_t i = 0;
+20 -20
View File
@@ -83,28 +83,28 @@ static cJSON *resume_page_to_json(struct page *page)
return json;
}
static cJSON *heap_item_to_json(int i, possibly_unused void *_)
{
if (!heap[i].ref)
return NULL;
cJSON *item = cJSON_CreateArray();
cJSON_AddItemToArray(item, cJSON_CreateNumber(i));
cJSON_AddItemToArray(item, cJSON_CreateNumber(heap[i].ref));
switch (heap[i].type) {
case VM_PAGE:
cJSON_AddItemToArray(item, resume_page_to_json(heap[i].page));
break;
case VM_STRING:
cJSON_AddItemToArray(item, cJSON_CreateString(heap[i].s->text));
break;
}
return item;
}
static cJSON *heap_to_json(void)
{
cJSON *json = cJSON_CreateArray();
for (size_t i = 0; i < heap_size; i++) {
if (!heap[i].ref)
continue;
cJSON *item = cJSON_CreateArray();
cJSON_AddItemToArray(item, cJSON_CreateNumber(i));
cJSON_AddItemToArray(item, cJSON_CreateNumber(heap[i].ref));
switch (heap[i].type) {
case VM_PAGE:
cJSON_AddItemToArray(item, resume_page_to_json(heap[i].page));
break;
case VM_STRING:
cJSON_AddItemToArray(item, cJSON_CreateString(heap[i].s->text));
break;
}
cJSON_AddItemToArray(json, item);
}
return json;
return cJSON_CreateArray_cb(heap_size, heap_item_to_json, NULL);
}
static cJSON *funcall_to_json(struct function_call *call)