c json实战引擎五 , 优化重构
引言
scjson是一个小巧的纯c跨平台小巧引擎. 适用于替换老的cJSON引擎的场景.
数据结构和代码布局做了大量改进.优势体现在以下几个方面:
1) 跨平台 (window 10 + VS2017 / ubuntu 16.10 + gcc 6.2 测试通过)
2) 数据结构重构(内存结构缩减了小一半)
3) 代码思路精简(全部加起来抛掉注释也许800行不到)
4) 支持json文本注释特性 // or /* */
5) 接口更少,更容易掌握全部
本文用到的资源
上一篇博文 c json实战引擎四 , 最后❤跳跃
内嵌到simplec框架的源码地址 https://github.com/wangzhione/simplec
其中需要用到的文件
scjson.h -> 解析json的接口文件
scjson.c -> 解析json的具体实现
tstr.h -> 和文件打交道用到的c字符串结构接口文件
tstr.c -> 和文件打交道用到的c字符串结构具体实现
扯个蛋, 写了无数的代码, 还是觉得写代码还是挺有意思的O(∩_∩)O哈哈~.
流浪记 http://music.163.com/#/song?id=26075648
前言
在说这里之前来点有意思点心, 不知道有木有人对malloc接口使用起来感觉很别扭.
详细一点可以了解 C基础 内存统一入口 .这里我们加深一下对malloc内部机制的理解,
首先看以前找的资料, 主要是linux上用户态申请内存最大大小是多少等.
malloc 一些解释 : https://www.zhihu.com/question/20836462
后面自己做了一些测试
#include <stdio.h>
#include <stdlib.h>
#include <limits.h> /*
* test calloc 返回结果信息
*/
int main(void) {
void * node; printf("UINT_MAX = %ld.\n", UINT_MAX); node = malloc(UINT_MAX);
printf("malloc UINT_MAX node = %p.\n", node);
if (node) {
puts("神奇!");
free(node);
} // 测试calloc 结果
node = calloc(UINT_MAX, sizeof(char));
printf("calloc UINT_MAX node = %p.\n", node);
if (node) {
puts("无语");
free(node);
} return ;
} //
// 测试结果 -> 系统蓝屏
// 结论 -> calloc 和 malloc 的行为是系统决定, assert也许是最好的选择
上面代码 run 之后, window 10系统直接蓝屏. 说明malloc/calloc 这类用户向系统要内存的函数, 都是不透明的.
都存在未定义行为. 因此得到的结论是
1. 需要分系统来处理malloc, windows申请大内存存在崩溃行为
2. 推荐以后关于 malloc / calloc 推荐用 assert 处理
上面是对malloc的解惑. 扯淡一点发现Microsoft 的 Visual Studio 2017 真厉害 , 黑科技太猛了, 强烈推荐尝试!!
到这里开始逐渐开始介绍scjson的设计思路了, 这里用到一个数据结构tstr . 设计结构图如下
完整代码可以在github上找, 还是挺不错的200行左右的代码, 加深对C字符串的理解.
这里再扯一点, str指向内存常变, tstr指向内存不怎么变. 所以采用两块内存保存,
方便后期优化, 例如加上字符串引用, 字符串枚举呀.
具体可以尝试了解对cloudwu字符串的解析博文 对云风 cstring 第二次解析
正文
这里主要讲解scjson 解析的思路. 开篇继续扯淡, 发现C11的匿名结构体或联合体挺爽的.
(好像C99就有).例如设计的c保存json节点结构
struct cjson {
struct cjson * next; // 采用链表结构处理, 放弃二叉树结构, 优化内存
struct cjson * child; // type == ( _CJSON_ARRAY or _CJSON_OBJECT ) 那么 child 就不为空 unsigned char type; // 数据类型和方式定义, 一个美好的意愿
char * key; // json内容那块的 key名称
union {
char * vs; // type == _CJSON_STRING, 是一个字符串
double vd; // type == _CJSON_NUMBER, 是一个num值, ((int)c->vd) 转成int 或 bool
};
};
其中 union 中 vs 和 vd. 其实在老的C89也可以实现这种效果, 具体在linux内核中有过一个小技巧.
union {
char * vs;
double vd;
};
伪造实现如下, 这种方式缺点是宏污染, 搞起来麻烦, 不好看.
union {
char * vs;
double vd;
} __v;
#define vs __v.vs
#define vd __v.vd
我们这里scjson 解析引擎内存结构如下:
详细一点代码类型就是
// json中几种数据结构和方式定义, 对于程序开发而言最难的还是理解思路(思想 or 业务)
#define _CJSON_FALSE (0u)
#define _CJSON_TRUE (1u)
#define _CJSON_NULL (1u << 1)
#define _CJSON_NUMBER (1u << 2)
#define _CJSON_STRING (1u << 3)
#define _CJSON_ARRAY (1u << 4)
#define _CJSON_OBJECT (1u << 5) #define _CJSON_ISREF (1u << 6) //set 时候用如果是引用就不释放了
#define _CJSON_ISCONST (1u << 7) //set 时候用, 如果是const char * 就不释放了
上面就是解析之后的具体结构类型. 下面简单分析一下文本解析规则.
主要思路就是递归下降分析. 到这里基本关于scjson详细设计图介绍完毕了.
去掉注释一共也许800行代码都不到, 愿这只麻雀 ヽ(✿゚▽゚)ノ
后记
On s'en va (Shy'm) http://music.163.com/m/song?id=29814206&userid=16529894
相濡以沫,不如相忘于江湖 -- 《庄子·大宗师·天运》
c json实战引擎五 , 优化重构的更多相关文章
- C json实战引擎 三 , 最后实现部分辅助函数
引言 大学读的是一个很时髦的专业, 学了四年的游戏竞技. 可惜没学好. 但认真过, 比做什么都认真. 见证了 ...... 打的所有游戏人物中 分享一位最喜爱 的 “I've been alone ...
- c json实战引擎四 , 最后❤跳跃
引言 - 以前那些系列 长活短说, 写的最终 scjson 纯c跨平台引擎, 希望在合适场景中替代老的csjon引擎, 速度更快, 更轻巧. 下面也是算一个系列吧. 从cjson 中得到灵感, 外加 ...
- C json实战引擎 二 , 实现构造部分
引言 这篇博文和前一篇 C json实战引擎一,实现解析部分设计是相同的,都是采用递归下降分析. 这里扯一点 假如你是学生 推荐一本书 给 大家 自制编程语言 http://baike.baidu.c ...
- C json实战引擎 一 , 实现解析部分
引言 以前可能是去年的去年,写了一个 c json 解析引擎用于一个统计实验数据项目开发中. 基本上能用. 去年在网上 看见了好多开源的c json引擎 .对其中一个比较标准的 cJSON 引擎 深入 ...
- c json实战引擎六 , 感觉还行
前言 看到六, 自然有 一二三四五 ... 为什么还要写呢. 可能是它还需要活着 : ) 挣扎升级中 . c json 上面代码也存在于下面项目中(维护的最及时) structc json 这次版本 ...
- .NET-架构优化实战-底层服务优化
原文:.NET-架构优化实战-底层服务优化 前言 问题分析 在本系列第一篇文章我们提到,底层问题主要存在以下两点: 代码冗余 时效低 代码冗余 例如: 领奖方法不统一,一次性的写一套,可循环的又写一套 ...
- [原创].NET 业务框架开发实战之六 DAL的重构
原文:[原创].NET 业务框架开发实战之六 DAL的重构 .NET 业务框架开发实战之六 DAL的重构 前言:其实这个系列还是之前的".NET 分布式架构开发实战 ",之所以改了 ...
- 第一章-Flink介绍-《Fink原理、实战与性能优化》读书笔记
Flink介绍-<Fink原理.实战与性能优化>读书笔记 1.1 Apache Flink是什么? 在当代数据量激增的时代,各种业务场景都有大量的业务数据产生,对于这些不断产生的数据应该如 ...
- Javascript多线程引擎(五)
Javascript多线程引擎(五)之异常处理 C语言没有提供一个像Java一样的异常处理机制, 这就带来了一个问题, 对于一个子函数中发生异常后, 需要在父函数调用子函数的位置进行Check, 如果 ...
随机推荐
- UVA.11464 Even Parity (思维题 开关问题)
UVA.11464 Even Parity (思维题 开关问题) 题目大意 给出一个n*n的01方格,现在要求将其中的一些0转换为1,使得每个方格的上下左右格子的数字和为偶数(如果存在的话),求使得最 ...
- bzoj1042: [HAOI2008]硬币购物(DP+容斥)
1600+人过的题排#32还不错嘿嘿 浴谷夏令营讲过的题,居然1A了 预处理出f[i]表示购买价值为i的东西的方案数 然后每次询问进行一次容斥,答案为总方案数-第一种硬币超限方案-第二种超限方案-第三 ...
- Codechef MARCH14 GERALD07加强版
强制在线不代表不能预处理! 考虑暴力怎么干? 开始n个联通块.now=n 不断加入边,如果连接两个联通块,--now 否则不动. 后者的前提是和[l,id-1]的边构成环 所以,我们考虑每个[l,r] ...
- BZOJ1832 聚会
Description:Y岛风景美丽宜人,气候温和,物产丰富.Y岛上有N个城市,有N-1条城市间的道路连接着它们.每一条道路都连接某两个城市.幸运的是,小可可通过这些道路可以走遍Y岛的所有城市.神奇的 ...
- apache出现You don't have permission to access / on this server. 提示
今天在新的linux上跑原来的代码,使用的虚拟主机的模式进行操作.几个相关的网站放在一个文件里,想法是通过网站列出的目录进行相应的网站进行操作.一切设置完成后,在浏览器中运行出现在You don't ...
- 软银开放Pepper开发,给机器人写安卓App是怎样一种体验?
日本软银推出的Pepper智能机器人 新浪科技讯 北京时间5月19日下午消息,谷歌Android移动操作系统的触角正在不断扩大,从今天开始,开发者可以为日本电信公司软银的Pepper人形机器人设计An ...
- caffe数据集——LMDB
LMDB介紹 Caffe使用LMDB來存放訓練/測試用的數據集,以及使用網絡提取出的feature(為了方便,以下還是統稱數據集).數據集的結構很簡單,就是大量的矩陣/向量數據平鋪開來.數據之間沒有什 ...
- C#学习之泛型
//主函数//主函数里面调用的类都在后面有具体描述 using System; using System.Collections.Generic; using System.Linq; using S ...
- 利用枚举算法实现todoList:把对应项添加的内容列表
功能: 点击城市列表项,如果内容列表不存在,则插入点击项: 如果内容列表中已存在,则不插入,然后把内容列表中的对应项放到第一位. HTML代码: <!DOCTYPE html> <h ...
- SpringMVC+MyBatis 返回时间格式转换的解决方案
Spring MVC 4.X ResponseBody 日期类型Json 处理 摘自http://tramp-zzy.iteye.com/blog/2090330 2014-07-10 方法一:全局 ...