
A high performance JSON library written in ANSI C.
Features
- Fast: can read or write gigabytes per second JSON data on modern CPU.
- Portable: compliance with ANSI C (C89).
- Standard: strict compliance with RFC 8259 standard.
- Safe: complete JSON form, number format and UTF-8 validation.
- Accuracy: can read and write
int64
, uint64
and double
numbers accurately.
- Less Restriction: support unlimited JSON level,
\u0000
and non null-terminated string.
- Extendable: options to allow comments, trailing commas, nan/inf, custom memory allocator.
- Developer Friendly: only one
h
and one c
file, easy to integrate.
Limitations
- An array or object is stored as some data structure like linked list, access elements with index or key is slower than iterator.
- Duplicate keys are allowed in an object, and the order of the keys is preserved.
- JSON parsing result is immutable, a
mutable copy
is required for modification.
Performance
Benchmark project and dataset: yyjson_benchmark
The simdjson's new On 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.
AWS EC2 (AMD EPYC 7R32, gcc 9.3)
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 |
iPhone (Apple A14, clang 12)
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 |
For better performance, yyjson prefers:
- A modern processor with:
- high instruction level parallelism
- excellent branch predictor
- low penalty for misaligned memory access
- A modern compiler with good optimizer.
Build and test
Manually
Just copy yyjson.h
and yyjson.c
to your project and start using it. Since yyjson
is ANSI C compatible, no other configuration is needed typically.
yyjson
has been tested with the following compilers: gcc
, clang
, msvc
, icc
, tcc
. If you find a compile error, please report a bug.
yyjson
has all features enabled by default, but you can trim out some of them by adding compile-time options. For example, disable JSON writer to reduce the binary size when you don't need serialization, or disable comments support to improve parsing performance. See compile-time options for details.
CMake
Clone the repository and create build directory:
git clone https://github.com/ibireme/yyjson.git
mkdir build
cd build
Build static library:
Build static library and run tests:
cmake .. -DYYJSON_BUILD_TESTS=ON
cmake --build .
ctest
Supported CMake options:
-DBUILD_SHARED_LIBS=ON
Build shared library instead of static library.
-DYYJSON_BUILD_TESTS=ON
Build all tests.
-DYYJSON_DISABLE_READER=ON
Disable JSON reader if you don't need it.
-DYYJSON_DISABLE_WRITER=ON
Disable JSON writer if you don't need it.
-DYYJSON_DISABLE_FAST_FP_CONV=ON
Disable fast floating-point number conversion.
-DYYJSON_DISABLE_NON_STANDARD=ON
Disable non-standard JSON support at compile-time.
More details
Sample Code
Read JSON string
const char *json = "{\"name\":\"Mash\",\"star\":4,\"hits\":[2,2,1,3]}";
size_t idx, max;
}
yyjson_api_inline yyjson_val * yyjson_obj_get(yyjson_val *obj, const char *key)
Definition: yyjson.h:3713
yyjson_api_inline int yyjson_get_int(yyjson_val *val)
Definition: yyjson.h:3574
#define yyjson_arr_foreach(arr, idx, max, val)
Definition: yyjson.h:1440
yyjson_api_inline const char * yyjson_get_str(yyjson_val *val)
Definition: yyjson.h:3582
yyjson_api_inline yyjson_val * yyjson_doc_get_root(yyjson_doc *doc)
Definition: yyjson.h:3442
yyjson_api_inline void yyjson_doc_free(yyjson_doc *doc)
Definition: yyjson.h:3454
yyjson_api_inline size_t yyjson_get_len(yyjson_val *val)
Definition: yyjson.h:3586
yyjson_api_inline yyjson_doc * yyjson_read(const char *dat, size_t len, yyjson_read_flag flg)
Definition: yyjson.h:738
Definition: yyjson.h:3271
Definition: yyjson.h:3266
Write JSON string
int hits_arr[] = {2, 2, 1, 3};
if (json) {
printf("json: %s\n", json);
free((void *)json);
}
yyjson_api_inline bool yyjson_mut_obj_add_val(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key, yyjson_mut_val *val)
Definition: yyjson.h:5417
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_with_sint32(yyjson_mut_doc *doc, const int32_t *vals, size_t count)
Definition: yyjson.h:4409
yyjson_api_inline bool yyjson_mut_obj_add_int(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key, int64_t val)
Definition: yyjson.h:5348
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj(yyjson_mut_doc *doc)
Definition: yyjson.h:5011
yyjson_api void yyjson_mut_doc_free(yyjson_mut_doc *doc)
yyjson_api_inline char * yyjson_mut_write(const yyjson_mut_doc *doc, yyjson_write_flag flg, size_t *len)
Definition: yyjson.h:1033
yyjson_api_inline void yyjson_mut_doc_set_root(yyjson_mut_doc *doc, yyjson_mut_val *root)
Definition: yyjson.h:3919
yyjson_api_inline bool yyjson_mut_obj_add_str(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key, const char *val)
Definition: yyjson.h:5368
yyjson_api yyjson_mut_doc * yyjson_mut_doc_new(const yyjson_alc *alc)
Definition: yyjson.h:3858
Definition: yyjson.h:3826
Read JSON file with options
if (doc) {
}
} else {
printf(
"read error (%u): %s at position: %ld\n", err.
code, err.
msg, err.
pos);
}
static const yyjson_read_flag YYJSON_READ_ALLOW_TRAILING_COMMAS
Definition: yyjson.h:588
yyjson_api_inline bool yyjson_obj_iter_init(yyjson_val *obj, yyjson_obj_iter *iter)
Definition: yyjson.h:3749
yyjson_api_inline yyjson_val * yyjson_obj_iter_get_val(yyjson_val *key)
Definition: yyjson.h:3776
uint32_t yyjson_read_flag
Definition: yyjson.h:561
yyjson_api_inline const char * yyjson_get_type_desc(yyjson_val *val)
Definition: yyjson.h:3542
yyjson_read_code code
Definition: yyjson.h:661
yyjson_api_inline yyjson_val * yyjson_obj_iter_next(yyjson_obj_iter *iter)
Definition: yyjson.h:3766
yyjson_api yyjson_doc * yyjson_read_file(const char *path, yyjson_read_flag flg, const yyjson_alc *alc, yyjson_read_err *err)
size_t pos
Definition: yyjson.h:665
const char * msg
Definition: yyjson.h:663
static const yyjson_read_flag YYJSON_READ_ALLOW_COMMENTS
Definition: yyjson.h:591
Definition: yyjson.h:3742
Write JSON file with options
}
}
printf(
"write error (%u): %s\n", err.
code, err.
msg);
}
yyjson_api yyjson_mut_doc * yyjson_doc_mut_copy(yyjson_doc *doc, const yyjson_alc *alc)
yyjson_api_inline bool yyjson_mut_is_null(yyjson_mut_val *val)
Definition: yyjson.h:3934
const char * msg
Definition: yyjson.h:875
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj_iter_next(yyjson_mut_obj_iter *iter)
Definition: yyjson.h:4944
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj_iter_remove(yyjson_mut_obj_iter *iter)
Definition: yyjson.h:4961
yyjson_api_inline yyjson_mut_val * yyjson_mut_doc_get_root(yyjson_mut_doc *doc)
Definition: yyjson.h:3915
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj_iter_get_val(yyjson_mut_val *key)
Definition: yyjson.h:4956
static const yyjson_write_flag YYJSON_WRITE_ESCAPE_UNICODE
Definition: yyjson.h:822
yyjson_api bool yyjson_mut_write_file(const char *path, const yyjson_mut_doc *doc, yyjson_write_flag flg, const yyjson_alc *alc, yyjson_write_err *err)
yyjson_api_inline bool yyjson_mut_obj_iter_init(yyjson_mut_val *obj, yyjson_mut_obj_iter *iter)
Definition: yyjson.h:4926
yyjson_write_code code
Definition: yyjson.h:873
static const yyjson_write_flag YYJSON_WRITE_PRETTY
Definition: yyjson.h:819
uint32_t yyjson_write_flag
Definition: yyjson.h:809
Definition: yyjson.h:4918
Documentation
TODO
- [x] Add documentation page.
- [x] Add GitHub workflow for CI and codecov.
- [x] Add more tests: valgrind, sanitizer.
- [x] Support JSON Pointer to query value from document.
- [x] Add fuzzer.
- [x] Add
RAW
type for JSON reader and writer.
- [ ] Add streaming API for JSON reader and writer.
- [ ] Add documentation about performance.
- [ ] Optimize performance for 32-bit processor.
License
This project is released under the MIT license.