optimize and simplify a bit: allow more efficient buffering - json2tsv - JSON to TSV converter
 (HTM) git clone git://git.codemadness.org/json2tsv
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 60cdcd6ec005e72e168f0318228371471121ad9b
 (DIR) parent f831a4b76c10d7efcb72effd18332f3deac7a4fa
 (HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
       Date:   Sun,  6 Oct 2019 16:20:13 +0200
       
       optimize and simplify a bit: allow more efficient buffering
       
       on a sample input using getchar_unlocked and putchar_unlocked parsed
       113MB of JSON data in 1.7 seconds vs 2.7.
       
       Tested with gcc and clang.
       
       Diffstat:
         M json2tsv.c                          |      26 +++++++++++++++-----------
       
       1 file changed, 15 insertions(+), 11 deletions(-)
       ---
 (DIR) diff --git a/json2tsv.c b/json2tsv.c
       @@ -24,9 +24,9 @@ enum JSONType {
        #define JSON_MAX_NODE_DEPTH 32
        
        struct json_node {
       +        enum JSONType type;
                char *name;
                size_t namesiz;
       -        enum JSONType type;
                size_t index; /* count/index for TYPE_ARRAY and TYPE_OBJECT */
        };
        
       @@ -251,9 +251,9 @@ printvalue(const char *s)
                for (; *s; s++) {
                        /* escape some chars */
                        switch (*s) {
       -                case '\n': fputs("\\n",  stdout); break;
       -                case '\\': fputs("\\\\", stdout); break;
       -                case '\t': fputs("\\t",  stdout); break;
       +                case '\n': putchar('\\'); putchar('n'); break;
       +                case '\\': putchar('\\'); putchar('\\'); break;
       +                case '\t': putchar('\\'); putchar('t'); break;
                        default:
                                /* ignore other control chars */
                                if (iscntrl((unsigned char)*s))
       @@ -278,20 +278,24 @@ processnode(struct json_node *nodes, size_t depth, const char *value)
                        if (nodes[i].type == TYPE_OBJECT) {
                                putchar('.');
                        } else if (nodes[i].type == TYPE_ARRAY) {
       -                        if (showindices)
       +                        if (showindices) {
                                        printf("[%zu]", nodes[i].index);
       -                        else
       -                                fputs("[]", stdout);
       +                        } else {
       +                                putchar('[');
       +                                putchar(']');
       +                        }
                        }
                }
        
       +        putchar('\t');
                switch (nodes[depth - 1].type) {
                case TYPE_UNKNOWN:   return;
       -        case TYPE_ARRAY:     fputs("\ta\t\n", stdout); return;
       -        case TYPE_OBJECT:    fputs("\to\t\n", stdout); return;
       -        case TYPE_PRIMITIVE: fputs("\tp\t",   stdout); break;
       -        case TYPE_STRING:    fputs("\ts\t",   stdout); break;
       +        case TYPE_ARRAY:     putchar('a'); break;
       +        case TYPE_OBJECT:    putchar('o'); break;
       +        case TYPE_PRIMITIVE: putchar('p'); break;
       +        case TYPE_STRING:    putchar('s'); break;
                }
       +        putchar('\t');
                printvalue(value);
                putchar('\n');
        }