c 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('\n'); p = s; for (unsigned char c = *p; (c); c = *++p) printf("\\u%04x", c); putchar('\n'); return 0; }
最终输出结果 (Ubuntu 环境)
wzhi@wzc:~/heoo/sizeof$ gcc char.c ; ./a.out \uffffffe4\uffffffbd\uffffffa0\uffffffe5\uffffffa5\uffffffbd \u00e4\u00bd\u00a0\u00e5\u00a5\u00bd 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 库要清爽很多.
虽是换汤不换药. 但性能会好些. 更加精简适合学习者学习.
欢迎尝试 ~ 不忘初衷 ~
后记
错误是难免, 欢迎指正互相交流, 消磨时间~
(今天, 不太好, 祝福受伤的人. 哎, 到底怎么了 ~ 我们都生病了 - )