Uma biblioteca JSON de alto desempenho escrita em ANSI C.
Rápido : pode ler ou gravar gigabytes por segundo de dados JSON em CPUs modernas.
Portátil : está em conformidade com ANSI C (C89) para compatibilidade entre plataformas.
Estrito : está em conformidade com o padrão JSON RFC 8259, garantindo formato numérico rigoroso e validação UTF-8.
Extensível : oferece opções para permitir comentários, vírgulas finais, NaN/Inf e alocador de memória personalizado.
Precisão : pode ler e escrever com precisão int64
, uint64
e números double
.
Flexível : suporta níveis de aninhamento JSON ilimitados, u0000
caracteres e strings não terminadas em nulo.
Manipulação : suporta consulta e modificação usando JSON Pointer, JSON Patch e JSON Merge Patch.
Amigável ao desenvolvedor : fácil integração com apenas um arquivo h
e um c
.
Uma matriz ou objeto é armazenado como uma estrutura de dados, como uma lista vinculada, o que torna o acesso aos elementos por índice ou chave mais lento do que usar um iterador.
Chaves duplicadas são permitidas em um objeto e a ordem das chaves é preservada.
O resultado da análise JSON é imutável, exigindo uma mutable copy
para modificação.
Projeto de referência e conjunto de dados: yyjson_benchmark
A nova API On Demand
do simdjson é mais rápida se a maioria dos campos JSON forem conhecidos em tempo de compilação. Este projeto de benchmark verifica apenas a API DOM, um novo benchmark será adicionado posteriormente.
twitter.json | analisar (GB/s) | stringificar (GB/s) |
---|---|---|
yyjson(insitu) | 1,80 | 1,51 |
yyjson | 1,72 | 1,42 |
simdjson | 1,52 | 0,61 |
sason | 1.16 | |
rapidjson(insitu) | 0,77 | |
rapidjson(utf8) | 0,26 | 0,39 |
cjson | 0,32 | 0,17 |
Jansson | 0,05 | 0,11 |
twitter.json | analisar (GB/s) | stringificar (GB/s) |
---|---|---|
yyjson(insitu) | 3.51 | 2.41 |
yyjson | 2,39 | 2.01 |
simdjson | 2.19 | 0,80 |
sason | 1,74 | |
rapidjson(insitu) | 0,75 | |
rapidjson(utf8) | 0h30 | 0,58 |
cjson | 0,48 | 0,33 |
Jansson | 0,09 | 0,24 |
Mais relatórios de benchmark com gráficos interativos (atualização 12/12/2020)
Plataforma | CPU | Compilador | SO | Relatório |
---|---|---|---|---|
Intel NUC8i5 | Núcleo i5-8259U | msvc 2019 | Windows 10 2004 | Gráficos |
Intel NUC8i5 | Núcleo i5-8259U | clangor 10.0 | Ubuntu 20.04 | Gráficos |
Intel NUC8i5 | Núcleo i5-8259U | gcc 9.3 | Ubuntu 20.04 | Gráficos |
AWS EC2 c5a.grande | AMD EPYC7R32 | gcc 9.3 | Ubuntu 20.04 | Gráficos |
AWS EC2 t4g.médio | Graviton2 (ARM64) | gcc 9.3 | Ubuntu 20.04 | Gráficos |
Apple iPhone 12 Pro | A14 (ARM64) | clangor 12.0 | iOS 14 | Gráficos |
Um processador moderno com:
paralelismo de alto nível de instrução
excelente preditor de ramificação
penalidade baixa para acesso desalinhado à memória
Um compilador moderno com bom otimizador (por exemplo, clang)
const char *json = "{"name":"Mash","star":4,"hits":[2,2,1,3]}";// Leia JSON e obtenha rootyyjson_doc *doc = yyjson_read(json , strlen(json), 0);yyjson_val *root = yyjson_doc_get_root(doc);// Obter root["nome"]yyjson_val *name = yyjson_obj_get(root, "nome");printf("nome: %sn", yyjson_get_str(nome));printf("comprimento do nome:%dn", (int)yyjson_get_len(nome));// Obter root["estrela "]yyjson_val *estrela = yyjson_obj_get(root, "estrela");printf("estrela: %dn", (int)yyjson_get_int(star));// Obtém root["hits"], itera sobre o arrayyyjson_val *hits = yyjson_obj_get(root, "hits");size_t idx, max;yyjson_val *hit;yyjson_arr_foreach(hits, idx, máximo, hit) {printf("hit%d:%dn", (int)idx, (int)yyjson_get_int(hit)); }// Libera o docyyjson_doc_free(doc); // Todas as funções aceitam entrada NULL e retornam NULL em caso de erro.
// Cria um mutável docyyjson_mut_doc *doc = yyjson_mut_doc_new(NULL);yyjson_mut_val *root = yyjson_mut_obj(doc);yyjson_mut_doc_set_root(doc, root);// Define root["name"] e root["star"]yyjson_mut_obj_add_str(doc, raiz, "nome", "Mash");yyjson_mut_obj_add_int(doc, root, "star", 4);// Definir root["hits"] com um arrayint 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);// Para string, minifiedconst char *json = yyjson_mut_write(doc, 0, NULL);if (json) {printf("json: %sn", json ); // {"name":"Mash","star":4,"hits":[2,2,1,3]}free((void *)json); }// Libera o docyyjson_mut_doc_free(doc);
// Lê o arquivo JSON, permitindo comentários e finais commasyyjson_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);// Iterar sobre o objeto raiz (doc) {yyjson_val *obj = yyjson_doc_get_root (doc); yyjson_obj_iter iter; yyjson_obj_iter_init (obj, &iter); , yyjson_get_str(chave), yyjson_get_type_desc(val)); } } else {printf("erro de leitura (%u): %s na posição: %ldn", err.code, err.msg, err.pos); }// Libera o docyyjson_doc_free(doc);
// Leia o arquivo JSON como um mutável 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 valores nulos na raiz objectyyjson_mut_obj_iter iter;yyjson_mut_obj_iter_init(obj, &iter);yyjson_mut_val *chave, *val;while ((chave = yyjson_mut_obj_iter_next(&iter))) {val = yyjson_mut_obj_iter_get_val(chave);se (yyjson_mut_is_null(val)) {yyjson_mut_obj_iter_remove(&iter); } }// Escreva o json bonito, escape unicodeyyjson_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("erro de gravação (%u): %sn", err.code, err.msg); }// Libera o docyyjson_doc_free(idoc);yyjson_mut_doc_free(doc);
A documentação mais recente (não lançada) pode ser acessada no diretório doc. O HTML Doxygen pré-gerado para a versão de lançamento pode ser visualizado aqui:
Página inicial
Construir e testar
API e código de exemplo
Estrutura de dados
Registro de alterações
Uma lista não exaustiva de projetos que expõem o yyjson a outras linguagens ou usam o yyjson internamente para um recurso importante. Se você tem um projeto que usa yyjson, fique à vontade para abrir um PR para adicioná-lo a esta lista.
Projeto | Linguagem | Descrição |
---|---|---|
py_yyjson | Pitão | Ligações Python para yyjson |
orjson | Pitão | Biblioteca JSON para Python com back-end yyjson opcional |
cpp-yyjson | C++ | Biblioteca C++ JSON com back-end yyjson |
refletir-cpp | C++ | Biblioteca C++ para serialização por meio de recuperação automatizada de nomes de campos de estruturas |
yyjsonr | R | Ligação R para yyjson |
Ananda | Rápido | Decodificação do modelo JSON baseada em yyjson |
patodb | C++ | DuckDB é um sistema de gerenciamento de banco de dados SQL OLAP em processo |
busca rápida | C | Uma ferramenta semelhante ao neofetch para buscar informações do sistema e exibi-las de uma forma bonita |
Ritmo | C | Estação de trabalho de áudio digital que usa yyjson para serializar arquivos de projeto JSON |
ser mais humano | C | Mecanismo de recomendação com foco na exclusividade da pessoa que recebe a recomendação |
mruby-yyjson | mruby | Biblioteca eficiente de análise e serialização JSON para mruby usando yyjson |
YYJSON.jl | Júlia | Ligações de Julia para yyjson |
Adicionar página de documentação.
Adicione o fluxo de trabalho do GitHub para CI e codecov.
Adicione mais testes: valgrind, sanitizer, fuzzing.
Suporte JSON Pointer para consultar e modificar JSON.
Adicione o tipo RAW
para leitor e gravador JSON.
Adicionada opção para limitar a precisão da saída de números reais.
Adicione opção para suportar JSON5 (se possível).
Adicione funções para diferenciar dois documentos JSON.
Adicione documentação sobre otimizações de desempenho.
Garanta a estabilidade da ABI.
Este projeto é lançado sob a licença do MIT.