zoukankan      html  css  js  c++  java
  • c json实战引擎六 , 感觉还行

    前言

      看到六, 自然有 一二三四五 ... 

      为什么还要写呢.  可能是它还需要活着 : ) 挣扎升级中 .

      c json 

      上面代码也存在于下面项目中(维护的最及时)

      structc json

      这次版本升级 (2018-02-11). 做的工作如下

        1. 修复了几个BUG

        2. 优化了 value 解析

        3. 优化了整体处理流程

      随后会简单介绍做的工作

    正文

    1. 修复了几个BUG

      介绍其中一个有意思的BUG, 关于 char 和 unsigned char 用法导致输出不一致.

    #include <stdio.h>
    
    int main(void) {
        char * p, * s = "你好";
        
        p = s;
        for (char c = *p; (c); c = *++p)
            printf("\u%04x", c);
        putchar('
    ');
        
        p = s;
        for (unsigned char c = *p; (c); c = *++p)
            printf("\u%04x", c);
        putchar('
    ');
    
        return 0;
    }

     最终输出结果 (Ubuntu 环境) 

    wzhi@wzc:~/heoo/sizeof$ gcc char.c ; ./a.out
    uffffffe4uffffffbduffffffa0uffffffe5uffffffa5uffffffbd
    u00e4u00bdu00a0u00e5u00a5u00bd
    wzhi@wzc:~/heoo/sizeof$ 

    通过上面可以看出 char 多输出内容. 导致内存最终和我们的预期不一致.

    还有些小 BUG, 不细说了, 留给有缘人赐予 wo 这样的人生机吧 ~ : )

    2. 优化了 value 解析

      value 分为 null, true, false, number, string, object, array 都有较多变化. 

    以 number 为例, 明显发现性能好了那么一盯点. 

    // number 分析
    static const char * _parse_number(json_t item, const char * str) {
        char c;
        int sign = 1;
        double n = 0;
        int e, esign;
    
        // 正负号处理判断
        if ((c = *str) == '-' || c == '+') {
            sign = c == '-' ? -1 : 1;
            c = *++str;
        }
    
        // 整数处理部分
        while (c >= '0' && c <= '9') {
            n = n * 10 + c - '0';
            c = *++str;
        }
        // 处理小数部分
        if (c == '.') {
            int d = 0;
            double s = 1;
            while ((c = *++str) && c >= '0' && c <= '9') {
                d = d * 10 + c - '0';
                s *= 0.1;
            }
            // 得到整数和小数部分
            n += s * d;
        }
    
        // 添加正负号
        n *= sign;
    
        // 不是科学计数内容直接返回
        item->type = JSON_NUMBER;
        if (c != 'e' && c != 'E') {
            item->vald = n;
            return str;
        }
    
        // 处理科学计数法
        if ((c = *++str) == '-' || c == '+')
            ++str;
        esign = c == '-' ? -1 : 1;
    
        e = 0;
        while ((c = *str) >= '0' && c <= '9') {
            e = e * 10 + c - '0';
            ++str;
        }
    
        // number = +/- number.fraction * 10^+/- exponent
        item->vald = n * pow(10, esign * e);
        return str;
    }

    增强了通用性. 降低了运行的函数栈大小.  值得推荐参照. 

    其它优化多在于去除了冗余字符指针的移动 ......

    3. 优化了整体处理流程

      例如 value parse 中已经检查到 '"' or '[' or '{' ... 抛给对应的处理模块就不需要

    再检查了. 整个流程是高度耦合. 性能好一点点. 

    以上就是我们当前做的操作. 整体而言. 当前这个 c json 库比 cJSON 库要清爽很多.

    虽是换汤不换药. 但性能会好些. 更加精简适合学习者学习.

    欢迎尝试 ~ 不忘初衷 ~ 

    后记

      错误是难免, 欢迎指正互相交流, 消磨时间~

      (今天, 不太好, 祝福受伤的人. 哎, 到底怎么了 ~ 我们都生病了 - ) 

  • 相关阅读:
    BZOJ 4571: [Scoi2016]美味
    LibreOJ #108. 多项式乘法
    BZOJ 4568: [Scoi2016]幸运数字
    BZOJ 4567: [Scoi2016]背单词
    fhq treap ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
    LibreOJ #6191. 「美团 CodeM 复赛」配对游戏
    LibreOJ #6212. 「美团 CodeM 决赛」melon
    LibreOJ #6192. 「美团 CodeM 复赛」城市网络
    LibreOJ #6220. sum
    AC日记——LOOPS hdu 3853
  • 原文地址:https://www.cnblogs.com/life2refuel/p/8441277.html
Copyright © 2011-2022 走看看