cJSON icon indicating copy to clipboard operation
cJSON copied to clipboard

Adjust the size of cJSON from 64 to 56 through memory alignment

Open yangbodong22011 opened this issue 4 years ago • 3 comments

By adjusting the position, the valueint and type memory are aligned, occupying a total of 8 bytes instead of 16 bytes, so sizeof(cJSON) is reduced from 64 bytes to 56 bytes.

p.s. Although this optimization may not be effective in the memory allocator's view, because the size that the allocator may allocate is 64 bytes, it may be effective in some scenarios, and it will not be worse than the current situation.

code:

#include <stdio.h>

/* The cJSON structure: */
typedef struct cJSON
{
    /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
    struct cJSON *next;
    struct cJSON *prev;
    /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
    struct cJSON *child;

    /* The type of the item, as above. */
    int type;

    /* The item's string, if type==cJSON_String  and type == cJSON_Raw */
    char *valuestring;
    /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
    int valueint;
    /* The item's number, if type==cJSON_Number */
    double valuedouble;

    /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
    char *string;
} cJSON;

/* The cJSON structure: */
typedef struct cJSONAfter
{
    /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
    struct cJSON *next;
    struct cJSON *prev;
    /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
    struct cJSON *child;

    /* The type of the item, as above. */
    int type;

    /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
    int valueint;
    /* The item's string, if type==cJSON_String  and type == cJSON_Raw */
    char *valuestring;
    /* The item's number, if type==cJSON_Number */
    double valuedouble;

    /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
    char *string;
} cJSONAfter;


int main() {

    printf("before: %lu ,after: %lu", sizeof(cJSON), sizeof(cJSONAfter));
    return 0;
}

$./a.out before: 64 ,after: 56

yangbodong22011 avatar Aug 17 '21 02:08 yangbodong22011

hi @yangbodong22011 , thanks your great contribution! This optimization could indeed save memory in some scenarios, but this is a breaking change, users need change the initiation of the cJSON struct, so it may merged in the next major version, such as 1.8 or 2.0

Alanscut avatar Aug 25 '21 07:08 Alanscut

@Alanscut Thanks for your reply, let's stay open and wait for more comments.

yangbodong22011 avatar Aug 25 '21 07:08 yangbodong22011

This is an ABI-break, not an API break. All that would be required here is incrementing the SOVERSION.

tristan957 avatar Dec 09 '21 17:12 tristan957