Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

workflow框架内置json解析器啦 #815

Open
Barenboim opened this issue Mar 19, 2022 · 11 comments
Open

workflow框架内置json解析器啦 #815

Barenboim opened this issue Mar 19, 2022 · 11 comments
Labels
documentation Improvements or additions to documentation enhancement New feature or request

Comments

@Barenboim
Copy link
Contributor

Barenboim commented Mar 19, 2022

为了实现对接Consul服务治理,需要引入json解析。调研过几个主流的json解析器都不是很满意,也不太想引入第三方库依赖。于是过年花了几天时间把json标准看了一遍实现了一个ANSI-C的json-parser,完整支持ECMA-404 json标准。之后也加入一些jons build的功能。主要接口如下:

json value相关接口

/* 解析json文档产生json value。返回json value对象。返回NULL代表解析失败(格式不标准,嵌套过深,分配内存失败)
   @doc 文档字符串 */
json_value_t *json_value_parse(const char *doc);

/* 销毁json value
   @val json value对象。一般由parse函数产生。*/
void json_value_destroy(json_value_t *val);

/* 返回json value类型
    可能的返回值:
    JSON_VALUE_STRING:字符串
    JSON_VALUE_NUMBER:数字
    JSON_VALUE_OBJECT:json对象
    JSON_VALUE_ARRAY:json数组
    JSON_VALUE_TRUE:true
    JSON_VALUE_FALSE:false
    JSON_VALUE_NULL:null
   @val:json value对象 */
int json_value_type(const json_value_t *val);

/* 获得json string。返回string地址。如果返回NULL,代表value不是STRING型。
   @val:json value对象 */
const char *json_value_string(const json_value_t *val);

/* 获得json number。返回数值。如果value不是NUMBER型,返回NAN(不存在的浮点数)。
   @val:json value对象 */
double json_value_number(const json_value_t *val);

/* 获得json object。返回object对象。如果value不是OBJECT类型,返回NULL。
   @val:json value对象
   注意返回的json_object_t指针并非const。可以通过build相关函数扩展object。*/
json_object_t *json_value_object(const json_value_t *val);

/* 获得json array。返回array对象。如果value不是ARRAY类型,返回NULL。
   @val:json value对象
   同样,返回的json_array_t指针不带const。 */
json_array_t *json_value_array(const json_value_t *val);

json object相关接口

/* 返回object的大小。即object包含的name,value对数量。
   @obj:json object对象 */
int json_object_size(const json_object_t *obj);

/* 查找name下的value。返回json value对象。返回NULL代表找不到这个name。函数时间复杂度为O(log(size))。
   @name:要查找的名字
   @obj:json object对象
   注意返回的json_value_t指针带const。*/
const json_value_t *json_object_find(const char *name, const json_object_t *obj);

/* 遍历json object。
   @name:临时的const char *类型name字符串
   @val:临时的const json_value_t *类型的json value对象
   @obj:json object对象
   这不是一个函数,是一个展开成一个for循环的宏。 */
json_object_for_each(name, val, obj)

json array相关接口

/* 返回json array的大小,即元素个数。
   @arr:json array对象 */
int json_array_size(const json_array_t *arr);

/* 遍历json array
   @val:临时的const json_value_t *类型的json value对象
   @arr:json array对象
   同样,这是一个展开成for循环的宏。 */
json_array_for_each(val, arr)

build接口

请直接参考源代码。

示例

使用示例大家可以到这个独立repo上看一下:
https://github.com/barenboim/json-parser
目前workflow的master分支,包括了这个json paser。所以,只需在代码里直接引用就可以了。

Benchmark

实测parse性能大概是cJSON的1.5倍,jsoncpp的10倍左右,但远低于rapidjsonsimdjson。cJSON的parse过程不包含建立查找表,因此对于大型json object,我们的find性能远高于cJSON。

@Barenboim Barenboim added enhancement New feature or request documentation Improvements or additions to documentation labels Mar 19, 2022
@worldflyingct
Copy link

请问既然性能不及rapidjson或simdjson,那为什么要自己造轮子呢?IO密集型的工作可以理解,但是json是cpu密集型的,网上查yyjson集成超简单,就两个文件。

@Barenboim
Copy link
Contributor Author

请问既然性能不及rapidjson或simdjson,那为什么要自己造轮子呢?IO密集型的工作可以理解,但是json是cpu密集型的,网上查yyjson集成超简单,就两个文件。

我们就是一路轮子到底的啊。最喜欢造轮子了。

@Barenboim
Copy link
Contributor Author

我们当时就是看了一圈都不满足,才想自己造。而且这个json-parser写得非常好非常标准,无论是学习还是使用,都是绝佳范例。yyjson比我们快很多,但代码也太大了。

@worldflyingct
Copy link

不错的工作氛围。我也自己手撸了一个mqtt服务器,当时是18年,市场上没发现有基于c/c++的异步非阻塞IO的开源服务器,就自己搞了一个。
但是由于自己手撸的mqttserver,发现加入了openssl库根本无法做到完全的静态编译,openssl库依赖cypto以及pthread等库。请问您们的workflow如果必须用openssl,会不会由于cypto以及pthread,导致无法100%无依赖?

@Barenboim
Copy link
Contributor Author

Barenboim commented May 2, 2022

不错的工作氛围。我也自己手撸了一个mqtt服务器,当时是18年,市场上没发现有基于c/c++的异步非阻塞IO的开源服务器,就自己搞了一个。 但是由于自己手撸的mqttserver,发现加入了openssl库根本无法做到完全的静态编译,openssl库依赖cypto以及pthread等库。请问您们的workflow如果必须用openssl,会不会由于cypto以及pthread,导致无法100%无依赖?

哈哈。怎么说呢,像openssl,大多数人已经默认为系统自带的了,所以我们也认为不算什么外部依赖。但仍然有用户在安装ssl上遇到麻烦。pthread属于posix的,对于unix系不用额外安装,可以放心使用。
我们认为多一个外部依赖至少损失50%新用户,所以能不依赖绝对不依赖。workflow里的kafka实现需要依赖几个压缩库,所以我们默认不编译kafka协议,减少用户的负担。

@worldflyingct
Copy link

嗯,但是我之前确实遇到过一个嵌入式平台完全不支持在线更新了,无法拉取官方openssl,又无法交叉编译,最后只能用go语言交叉编译一个出来。
因此如果你们真的在乎完全无依赖,可以尝试使用mbedtls代替openssl,它是用C写的,没有任何外部依赖,Apache License 2.0。
我也会尝试使用musl-libc代理glibc的方式实现真正的无依赖编译(网上有说musl-libc交叉编译支持更好),对于我们做物联网的公司,交叉编译太重要了。

@Barenboim
Copy link
Contributor Author

嗯,但是我之前确实遇到过一个嵌入式平台完全不支持在线更新了,无法拉取官方openssl,又无法交叉编译,最后只能用go语言交叉编译一个出来。 因此如果你们真的在乎完全无依赖,可以尝试使用mbedtls代替openssl,它是用C写的,没有任何外部依赖,Apache License 2.0。 我也会尝试使用musl-libc代理glibc的方式实现真正的无依赖编译(网上有说musl-libc交叉编译支持更好),对于我们做物联网的公司,交叉编译太重要了。

我们有个nossl分支不需要ssl。但目前还需要链接crypto,因为用了md5和sha1。这两个模块其实可以代替。

@worldflyingct
Copy link

嗯,但是我之前确实遇到过一个嵌入式平台完全不支持在线更新了,无法拉取官方openssl,又无法交叉编译,最后只能用go语言交叉编译一个出来。 因此如果你们真的在乎完全无依赖,可以尝试使用mbedtls代替openssl,它是用C写的,没有任何外部依赖,Apache License 2.0。 我也会尝试使用musl-libc代理glibc的方式实现真正的无依赖编译(网上有说musl-libc交叉编译支持更好),对于我们做物联网的公司,交叉编译太重要了。

我们有个nossl分支不需要ssl。但目前还需要链接crypto,因为用了md5和sha1。这两个模块其实可以代替。

我这里有纯C语言算法实现的md5、sha1与sha256的代码,经过测试毫无依赖且结果正确,我甚至在自己的单片机项目中已经使用了,如何提交给你们???

@Barenboim
Copy link
Contributor Author

Barenboim commented May 3, 2022 via email

@lzz231
Copy link

lzz231 commented Aug 14, 2023

我们当时就是看了一圈都不满足,才想自己造。而且这个json-parser写得非常好非常标准,无论是学习还是使用,都是绝佳范例。yyjson比我们快很多,但代码也太大了。

有json对象转换成字符串的接口嘛,我好像没有看到。

@Barenboim
Copy link
Contributor Author

Barenboim commented Aug 14, 2023

我们当时就是看了一圈都不满足,才想自己造。而且这个json-parser写得非常好非常标准,无论是学习还是使用,都是绝佳范例。yyjson比我们快很多,但代码也太大了。

有json对象转换成字符串的接口嘛,我好像没有看到。

没有,workflow里的json,没有提供序列号接口,你可以看看我的序列化的示例:https://github.com/barenboim/json-parser
也可以用wfrest的JSON,基于workflow的JSON封装的,你把.h和.cc拷过去就可以了:https://github.com/wfrest/Json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants