- Notifications
You must be signed in to change notification settings - Fork301
The fastest JSON library in C
License
ibireme/yyjson
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
A high performance JSON library written in ANSI C.
- Fast: can read or write gigabytes of JSON data per second on modern CPUs.
- Portable: complies with ANSI C (C89) for cross-platform compatibility.
- Strict: complies withRFC 8259 JSON standard, ensuring strict number formats and UTF-8 validation.
- Extendable: offers options to enable individualJSON5 features and custom allocator.
- Accuracy: can accurately read and write
int64,uint64, anddoublenumbers. - Flexible: supports unlimited JSON nesting levels,
\u0000characters, and non-null-terminated strings. - Manipulation: supports querying and modifying withJSON Pointer,JSON Patch, andJSON Merge Patch.
- Developer-Friendly: easy integration with just one
.hand one.cfile.
- An array or object is stored as adata structure such as linked list, which makes accessing elements by index or key slower than using an iterator.
- Duplicate keys are allowed in an object, and the order of the keys is preserved.
- JSON parsing result is immutable, requiring a
mutable copyfor modification.
Benchmark project and dataset:yyjson_benchmark
The simdjson's newOn Demand API is faster if most JSON fields are known at compile-time.This benchmark project only checks the DOM API, a new benchmark will be added later.
| twitter.json | parse (GB/s) | stringify (GB/s) |
|---|---|---|
| yyjson(insitu) | 1.80 | 1.51 |
| yyjson | 1.72 | 1.42 |
| simdjson | 1.52 | 0.61 |
| sajson | 1.16 | |
| rapidjson(insitu) | 0.77 | |
| rapidjson(utf8) | 0.26 | 0.39 |
| cjson | 0.32 | 0.17 |
| jansson | 0.05 | 0.11 |
| twitter.json | parse (GB/s) | stringify (GB/s) |
|---|---|---|
| yyjson(insitu) | 3.51 | 2.41 |
| yyjson | 2.39 | 2.01 |
| simdjson | 2.19 | 0.80 |
| sajson | 1.74 | |
| rapidjson(insitu) | 0.75 | |
| rapidjson(utf8) | 0.30 | 0.58 |
| cjson | 0.48 | 0.33 |
| jansson | 0.09 | 0.24 |
More benchmark reports with interactive charts (update 2020-12-12)
| Platform | CPU | Compiler | OS | Report |
|---|---|---|---|---|
| Intel NUC 8i5 | Core i5-8259U | msvc 2019 | Windows 10 2004 | Charts |
| Intel NUC 8i5 | Core i5-8259U | clang 10.0 | Ubuntu 20.04 | Charts |
| Intel NUC 8i5 | Core i5-8259U | gcc 9.3 | Ubuntu 20.04 | Charts |
| AWS EC2 c5a.large | AMD EPYC 7R32 | gcc 9.3 | Ubuntu 20.04 | Charts |
| AWS EC2 t4g.medium | Graviton2 (ARM64) | gcc 9.3 | Ubuntu 20.04 | Charts |
| Apple iPhone 12 Pro | A14 (ARM64) | clang 12.0 | iOS 14 | Charts |
- A modern processor with:
- high instruction level parallelism
- excellent branch predictor
- low penalty for misaligned memory access
- A modern compiler with good optimizer (e.g. clang)
constchar*json="{\"name\":\"Mash\",\"star\":4,\"hits\":[2,2,1,3]}";// Read JSON and get rootyyjson_doc*doc=yyjson_read(json,strlen(json),0);yyjson_val*root=yyjson_doc_get_root(doc);// Get root["name"]yyjson_val*name=yyjson_obj_get(root,"name");printf("name: %s\n",yyjson_get_str(name));printf("name length:%d\n", (int)yyjson_get_len(name));// Get root["star"]yyjson_val*star=yyjson_obj_get(root,"star");printf("star: %d\n", (int)yyjson_get_int(star));// Get root["hits"], iterate over the arrayyyjson_val*hits=yyjson_obj_get(root,"hits");size_tidx,max;yyjson_val*hit;yyjson_arr_foreach(hits,idx,max,hit) {printf("hit%d: %d\n", (int)idx, (int)yyjson_get_int(hit));}// Free the docyyjson_doc_free(doc);// All functions accept NULL input, and return NULL on error.
// Create a mutable docyyjson_mut_doc*doc=yyjson_mut_doc_new(NULL);yyjson_mut_val*root=yyjson_mut_obj(doc);yyjson_mut_doc_set_root(doc,root);// Set root["name"] and root["star"]yyjson_mut_obj_add_str(doc,root,"name","Mash");yyjson_mut_obj_add_int(doc,root,"star",4);// Set root["hits"] with an arrayinthits_arr[]= {2,2,1,3};yyjson_mut_val*hits=yyjson_mut_arr_with_sint32(doc,hits_arr,4);yyjson_mut_obj_add_val(doc,root,"hits",hits);// To string, minifiedconstchar*json=yyjson_mut_write(doc,0,NULL);if (json) {printf("json: %s\n",json);// {"name":"Mash","star":4,"hits":[2,2,1,3]}free((void*)json);}// Free the docyyjson_mut_doc_free(doc);
// Read JSON file, allowing comments and trailing commasyyjson_read_flagflg=YYJSON_READ_ALLOW_COMMENTS |YYJSON_READ_ALLOW_TRAILING_COMMAS;yyjson_read_errerr;yyjson_doc*doc=yyjson_read_file("/tmp/config.json",flg,NULL,&err);// Iterate over the root objectif (doc) {yyjson_val*obj=yyjson_doc_get_root(doc);yyjson_obj_iteriter;yyjson_obj_iter_init(obj,&iter);yyjson_val*key,*val;while ((key=yyjson_obj_iter_next(&iter))) {val=yyjson_obj_iter_get_val(key);printf("%s: %s\n",yyjson_get_str(key),yyjson_get_type_desc(val)); }}else {printf("read error (%u): %s at position: %ld\n",err.code,err.msg,err.pos);}// Free the docyyjson_doc_free(doc);
// Read the JSON file as a mutable docyyjson_doc*idoc=yyjson_read_file("/tmp/config.json",0,NULL,NULL);yyjson_mut_doc*doc=yyjson_doc_mut_copy(idoc,NULL);yyjson_mut_val*obj=yyjson_mut_doc_get_root(doc);// Remove null values in root objectyyjson_mut_obj_iteriter;yyjson_mut_obj_iter_init(obj,&iter);yyjson_mut_val*key,*val;while ((key=yyjson_mut_obj_iter_next(&iter))) {val=yyjson_mut_obj_iter_get_val(key);if (yyjson_mut_is_null(val)) {yyjson_mut_obj_iter_remove(&iter); }}// Write the json pretty, escape unicodeyyjson_write_flagflg=YYJSON_WRITE_PRETTY |YYJSON_WRITE_ESCAPE_UNICODE;yyjson_write_errerr;yyjson_mut_write_file("/tmp/config.json",doc,flg,NULL,&err);if (err.code) {printf("write error (%u): %s\n",err.code,err.msg);}// Free the docyyjson_doc_free(idoc);yyjson_mut_doc_free(doc);
The latest (unreleased) documentation can be accessed in thedoc directory.The pre-generated Doxygen HTML for the release version can be viewed here:
A non-exhaustive list of projects that expose yyjson to other languages oruse yyjson internally for a major feature. If you have a project that usesyyjson, feel free to open a PR to add it to this list.
| Project | Language | Description |
|---|---|---|
| py_yyjson | Python | Python bindings for yyjson |
| orjson | Python | JSON library for Python with an optional yyjson backend |
| serin | C++ / Python | a C++ and Python serialization library supporting TOON, JSON, and YAML with cross-format conversion. |
| cpp-yyjson | C++ | C++ JSON library with a yyjson backend |
| reflect-cpp | C++ | C++ library for serialization through automated field name retrieval from structs |
| yyjsonr | R | R binding for yyjson |
| Ananda | Swift | JSON model decoding based on yyjson |
| ReerJSON | Swift | A faster version of JSONDecoder based on yyjson |
| duckdb | C++ | DuckDB is an in-process SQL OLAP Database Management System |
| fastfetch | C | A neofetch-like tool for fetching system information and displaying them in a pretty way |
| Zrythm | C | Digital Audio Workstation that uses yyjson to serialize JSON project files |
| bemorehuman | C | Recommendation engine with a focus on uniqueness of the person receiving the rec |
| mruby-yyjson | mruby | Efficient JSON parsing and serialization library for mruby using yyjson |
| YYJSON.jl | Julia | Julia bindings for yyjson |
- Add documentation page.
- Add GitHub workflow for CI and codecov.
- Add more tests: valgrind, sanitizer, fuzzing.
- Support JSON Pointer to query and modify JSON.
- Add
RAWtype for JSON reader and writer. - Add option to limit real number output precision.
- Add option to support JSON5.
- Add functions to diff two JSON documents.
- Add documentation on performance optimizations.
- Ensure ABI stability.
This project is released under the MIT license.
About
The fastest JSON library in C
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.