Convert Figma logo to code with AI

ibireme logoyyjson

The fastest JSON library in C

3,042
262
3,042
9

Top Related Projects

19,071

Parsing gigabytes of JSON per second : used by Facebook/Meta Velox, the Node.js runtime, ClickHouse, WatermelonDB, Apache Doris, Milvus, StarRocks

14,146

A fast JSON parser/generator for C++ with both SAX/DOM style API

42,154

JSON for Modern C++

C/C++ JSON parser/generator benchmark

3,648

Jsmn is a world fastest JSON parser/tokenizer. This is the official repo replacing the old one at Bitbucket

Quick Overview

yyjson is a high-performance JSON library written in ANSI C. It provides fast JSON parsing and serialization capabilities, with a focus on speed and efficiency. The library is designed to be lightweight, easy to use, and suitable for various platforms and applications.

Pros

  • Extremely fast JSON parsing and serialization
  • Low memory usage and zero dependencies
  • Supports both UTF-8 and UTF-16 encoding
  • Provides both mutable and immutable APIs

Cons

  • Limited to C and C++ languages
  • May require manual memory management in some cases
  • Less feature-rich compared to some larger JSON libraries
  • Relatively new project, potentially less battle-tested than more established alternatives

Code Examples

  1. Parsing JSON:
const char *json = "{\"name\":\"John\",\"age\":30}";
yyjson_doc *doc = yyjson_read(json, strlen(json), 0);
yyjson_val *root = yyjson_doc_get_root(doc);

const char *name = yyjson_get_str(yyjson_obj_get(root, "name"));
int age = yyjson_get_int(yyjson_obj_get(root, "age"));

printf("Name: %s, Age: %d\n", name, age);

yyjson_doc_free(doc);
  1. Creating and serializing JSON:
yyjson_mut_doc *doc = yyjson_mut_doc_new(NULL);
yyjson_mut_val *root = yyjson_mut_obj(doc);
yyjson_mut_doc_set_root(doc, root);

yyjson_mut_obj_add_str(doc, root, "name", "Alice");
yyjson_mut_obj_add_int(doc, root, "age", 25);

char *json = yyjson_mut_write(doc, 0, NULL);
printf("%s\n", json);

free(json);
yyjson_mut_doc_free(doc);
  1. Working with arrays:
const char *json = "[1,2,3,4,5]";
yyjson_doc *doc = yyjson_read(json, strlen(json), 0);
yyjson_val *arr = yyjson_doc_get_root(doc);

size_t idx, max;
yyjson_val *val;
yyjson_arr_foreach(arr, idx, max, val) {
    printf("%d ", yyjson_get_int(val));
}

yyjson_doc_free(doc);

Getting Started

To use yyjson in your project:

  1. Download the yyjson.h and yyjson.c files from the GitHub repository.
  2. Include them in your project:
#include "yyjson.h"
  1. Compile your project with the yyjson.c file:
gcc your_file.c yyjson.c -o your_program
  1. Start using yyjson functions in your code as shown in the examples above.

Competitor Comparisons

19,071

Parsing gigabytes of JSON per second : used by Facebook/Meta Velox, the Node.js runtime, ClickHouse, WatermelonDB, Apache Doris, Milvus, StarRocks

Pros of simdjson

  • Utilizes SIMD instructions for faster parsing
  • Supports in-situ parsing, reducing memory usage
  • Offers both DOM and streaming APIs for flexibility

Cons of simdjson

  • Limited to parsing only, no JSON generation capabilities
  • Requires CPU support for specific SIMD instructions
  • Larger codebase and more complex implementation

Code Comparison

simdjson:

simdjson::dom::parser parser;
simdjson::dom::element doc = parser.parse(json_string);
std::string_view result = doc["key"];

yyjson:

yyjson_doc *doc = yyjson_read(json_string, strlen(json_string), 0);
yyjson_val *val = yyjson_obj_get(yyjson_doc_get_root(doc), "key");
const char *result = yyjson_get_str(val);

Key Differences

  • simdjson focuses on high-performance parsing using SIMD instructions
  • yyjson offers a more comprehensive JSON handling solution, including both parsing and generation
  • simdjson provides C++ APIs, while yyjson is primarily C-based
  • yyjson has a smaller codebase and simpler implementation
  • simdjson may have better performance for large JSON documents on supported hardware

Both libraries are well-maintained and offer efficient JSON parsing capabilities, but they cater to different use cases and programming environments.

14,146

A fast JSON parser/generator for C++ with both SAX/DOM style API

Pros of rapidjson

  • More mature and widely adopted in production environments
  • Supports both DOM and SAX parsing styles
  • Extensive documentation and community support

Cons of rapidjson

  • Larger codebase and memory footprint
  • Slower parsing and serialization speed compared to yyjson
  • More complex API, potentially steeper learning curve

Code Comparison

yyjson:

yyjson_doc *doc = yyjson_read(json, len, 0);
yyjson_val *root = yyjson_doc_get_root(doc);
const char *name = yyjson_get_str(yyjson_obj_get(root, "name"));
yyjson_doc_free(doc);

rapidjson:

Document d;
d.Parse(json);
const char* name = d["name"].GetString();

Key Differences

  • yyjson is written in C, while rapidjson is in C++
  • yyjson focuses on simplicity and performance, while rapidjson offers more features
  • yyjson has a smaller codebase and is easier to integrate into projects
  • rapidjson provides more flexibility with its DOM and SAX parsing options

Both libraries are high-performance JSON parsers, but they cater to different use cases. yyjson excels in scenarios where speed and simplicity are paramount, while rapidjson is better suited for complex applications requiring advanced JSON manipulation features.

42,154

JSON for Modern C++

Pros of json

  • Widely adopted and well-established in the C++ community
  • Extensive documentation and examples available
  • Supports both SAX and DOM parsing styles

Cons of json

  • Slower performance compared to yyjson, especially for large JSON files
  • Higher memory usage due to its design and implementation
  • More complex API, which may require a steeper learning curve

Code Comparison

yyjson:

yyjson_doc *doc = yyjson_read(json_str, strlen(json_str), 0);
yyjson_val *root = yyjson_doc_get_root(doc);
const char *name = yyjson_get_str(yyjson_obj_get(root, "name"));
yyjson_doc_free(doc);

json:

auto j = json::parse(json_str);
std::string name = j["name"];

While json provides a more concise API for simple operations, yyjson offers finer control over memory allocation and parsing options. yyjson's C API may be more verbose but allows for better performance optimization in certain scenarios.

Both libraries support serialization and deserialization of JSON data, but yyjson focuses on high performance and low memory usage, making it particularly suitable for applications dealing with large JSON files or requiring minimal resource consumption.

C/C++ JSON parser/generator benchmark

Pros of nativejson-benchmark

  • Comprehensive benchmarking of multiple JSON libraries
  • Provides detailed performance metrics for parsing and serialization
  • Includes a wide range of test cases and data sets

Cons of nativejson-benchmark

  • Primarily focused on benchmarking, not a standalone JSON library
  • May not reflect real-world usage scenarios for all applications
  • Requires more setup and configuration to use in projects

Code Comparison

nativejson-benchmark (benchmarking setup):

void BM_RapidJsonInsitu(benchmark::State& state) {
    for (auto _ : state)
        ParseInsitu<rapidjson::Document>(json);
}
BENCHMARK(BM_RapidJsonInsitu);

yyjson (parsing example):

yyjson_doc *doc = yyjson_read(json, len, 0);
yyjson_val *root = yyjson_doc_get_root(doc);
// Use the parsed JSON
yyjson_doc_free(doc);

Summary

nativejson-benchmark is a tool for comparing JSON library performance, while yyjson is a high-performance JSON library. nativejson-benchmark offers comprehensive benchmarking across multiple libraries, but requires more setup. yyjson provides a simple API for JSON parsing and serialization, focusing on performance and ease of use in applications.

3,648

Jsmn is a world fastest JSON parser/tokenizer. This is the official repo replacing the old one at Bitbucket

Pros of jsmn

  • Extremely lightweight and simple to use
  • No dynamic memory allocation, suitable for embedded systems
  • Single-file implementation, easy to integrate

Cons of jsmn

  • Limited functionality compared to yyjson
  • Requires manual parsing of JSON values
  • No built-in support for JSON creation or modification

Code Comparison

jsmn:

jsmn_parser p;
jsmntok_t t[128];
jsmn_init(&p);
int r = jsmn_parse(&p, json_string, strlen(json_string), t, sizeof(t)/sizeof(t[0]));

yyjson:

yyjson_doc *doc = yyjson_read(json_string, strlen(json_string), 0);
yyjson_val *root = yyjson_doc_get_root(doc);

Summary

jsmn is a minimalist JSON parser focused on simplicity and low memory footprint, making it ideal for embedded systems. However, it lacks advanced features and requires more manual work for parsing and handling JSON data.

yyjson, on the other hand, offers a more comprehensive JSON manipulation library with better performance and easier-to-use APIs. It provides additional functionality like JSON creation and modification, making it more suitable for complex JSON processing tasks in larger applications.

The choice between the two depends on the specific requirements of the project, such as memory constraints, performance needs, and the complexity of JSON operations required.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Introduction

Build Codecov License Version Packaging status

A high performance JSON library written in ANSI C.

Features

  • Fast: can read or write gigabytes per second JSON data on modern CPUs.
  • Portable: complies with ANSI C (C89) for cross-platform compatibility.
  • Strict: complies with RFC 8259 JSON standard, ensuring strict number format and UTF-8 validation.
  • Extendable: offers options to allow comments, trailing commas, NaN/Inf, and custom memory allocator.
  • Accuracy: can accurately read and write int64, uint64, and double numbers.
  • Flexible: supports unlimited JSON nesting levels, \u0000 characters, and non null-terminated strings.
  • Manipulation: supports querying and modifying using JSON Pointer, JSON Patch and JSON Merge Patch.
  • Developer-Friendly: easy integration with only one h and one c file.

Limitations

  • An array or object is stored as a data 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 copy 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)

ec2_chart

twitter.jsonparse (GB/s)stringify (GB/s)
yyjson(insitu)1.801.51
yyjson1.721.42
simdjson1.520.61
sajson1.16
rapidjson(insitu)0.77
rapidjson(utf8)0.260.39
cjson0.320.17
jansson0.050.11

iPhone (Apple A14, clang 12)

a14_chart

twitter.jsonparse (GB/s)stringify (GB/s)
yyjson(insitu)3.512.41
yyjson2.392.01
simdjson2.190.80
sajson1.74
rapidjson(insitu)0.75
rapidjson(utf8)0.300.58
cjson0.480.33
jansson0.090.24

More benchmark reports with interactive charts (update 2020-12-12)

PlatformCPUCompilerOSReport
Intel NUC 8i5Core i5-8259Umsvc 2019Windows 10 2004Charts
Intel NUC 8i5Core i5-8259Uclang 10.0Ubuntu 20.04Charts
Intel NUC 8i5Core i5-8259Ugcc 9.3Ubuntu 20.04Charts
AWS EC2 c5a.largeAMD EPYC 7R32gcc 9.3Ubuntu 20.04Charts
AWS EC2 t4g.mediumGraviton2 (ARM64)gcc 9.3Ubuntu 20.04Charts
Apple iPhone 12 ProA14 (ARM64)clang 12.0iOS 14Charts

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 (e.g. clang)

Sample Code

Read JSON string

const char *json = "{\"name\":\"Mash\",\"star\":4,\"hits\":[2,2,1,3]}";

// Read JSON and get root
yyjson_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 array
yyjson_val *hits = yyjson_obj_get(root, "hits");
size_t idx, 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 doc
yyjson_doc_free(doc);

// All functions accept NULL input, and return NULL on error.

Write JSON string

// Create a mutable doc
yyjson_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 array
int hits_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, minified
const char *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 doc
yyjson_mut_doc_free(doc);

Read JSON file with options

// Read JSON file, allowing comments and trailing commas
yyjson_read_flag flg = YYJSON_READ_ALLOW_COMMENTS | YYJSON_READ_ALLOW_TRAILING_COMMAS;
yyjson_read_err err;
yyjson_doc *doc = yyjson_read_file("/tmp/config.json", flg, NULL, &err);

// Iterate over the root object
if (doc) {
    yyjson_val *obj = yyjson_doc_get_root(doc);
    yyjson_obj_iter iter;
    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 doc
yyjson_doc_free(doc);

Write JSON file with options

// Read the JSON file as a mutable doc
yyjson_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 object
yyjson_mut_obj_iter iter;
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 unicode
yyjson_write_flag flg = YYJSON_WRITE_PRETTY | YYJSON_WRITE_ESCAPE_UNICODE;
yyjson_write_err err;
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 doc
yyjson_doc_free(idoc);
yyjson_mut_doc_free(doc);

Documentation

The latest (unreleased) documentation can be accessed in the doc directory. The pre-generated Doxygen HTML for the release version can be viewed here:

Packaging status

Packaging status

Built With yyjson

A non-exhaustive list of projects that expose yyjson to other languages or use yyjson internally for a major feature. If you have a project that uses yyjson, feel free to open a PR to add it to this list.

ProjectLanguageDescription
py_yyjsonPythonPython bindings for yyjson
orjsonPythonJSON library for Python with an optional yyjson backend
cpp-yyjsonC++C++ JSON library with a yyjson backend
reflect-cppC++C++ library for serialization through automated field name retrieval from structs
yyjsonrRR binding for yyjson
AnandaSwiftJSON model decoding based on yyjson
duckdbC++DuckDB is an in-process SQL OLAP Database Management System
fastfetchCA neofetch-like tool for fetching system information and displaying them in a pretty way
ZrythmCDigital Audio Workstation that uses yyjson to serialize JSON project files
bemorehumanCRecommendation engine with a focus on uniqueness of the person receiving the rec
mruby-yyjsonmrubyEfficient JSON parsing and serialization library for mruby using yyjson

TODO for v1.0

  • 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 RAW type for JSON reader and writer.
  • Add option to limit real number output precision.
  • Add option to support JSON5 (if feasible).
  • Add functions to diff two JSON documents.
  • Add documentation on performance optimizations.
  • Ensure ABI stability.

License

This project is released under the MIT license.