{yyjsonr}
is a fast JSON parser/serializer, which converts R data to/from JSON, GeoJSON and NDJSON.
In most cases it is around 2x to 10x faster than jsonlite at both reading and writing JSON.
It is based around the yyjson
C library.
If you have an interest in fast JSON reading/writing in R, then I need your help.
The scope of this package and options it supports are still in flux. What can I add to help your JSON needs? Open an issue on github and let me know!
You can assist by:
yyjson
C library
This package includes the yyjson
C library (version YYJSON_VERSION_HEX = 0x000700
).
yysjon
is MIT licensed - see LICENSE-yyjson.txt
in this package for more details.
R to JSON | JSON to R | ndjson read | ndjson write | geojson to/from sf | |
---|---|---|---|---|---|
yyjsonr | Fast! | Fast! | Fast! | Fast! | Fast! |
jsonlite | Yes | Yes | Yes | Yes | |
RcppSimdJson | Fast! | ||||
jsonify | Yes | Yes | Yes | Yes | |
ndjson | Yes | Yes | |||
geojsonsf | Yes |
Note: Benchmarks were run on Apple M2 Mac. See file “man/benchmark/benchmark.Rmd” for details.
You can install from GitHub with:
# install.package('remotes')
remotes::install_github('coolbutuseless/yyjsonr')
library(yyjsonr)
str <- to_json_str(head(iris, 3), pretty = TRUE)
cat(str)
#> [
#> {
#> "Sepal.Length": 5.1,
#> "Sepal.Width": 3.5,
#> "Petal.Length": 1.4,
#> "Petal.Width": 0.2,
#> "Species": "setosa"
#> },
#> {
#> "Sepal.Length": 4.9,
#> "Sepal.Width": 3.0,
#> "Petal.Length": 1.4,
#> "Petal.Width": 0.2,
#> "Species": "setosa"
#> },
#> {
#> "Sepal.Length": 4.7,
#> "Sepal.Width": 3.2,
#> "Petal.Length": 1.3,
#> "Petal.Width": 0.2,
#> "Species": "setosa"
#> }
#> ]
from_json_str(str)
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1 5.1 3.5 1.4 0.2 setosa
#> 2 4.9 3.0 1.4 0.2 setosa
#> 3 4.7 3.2 1.3 0.2 setosa
{jsonlite}
Numeric conversion is handled within the yyjson
C library and is not configuraable.
In {yyjsonr}
the order in which elements in an array are serialized to JSON correspond to an array of row-major matrices in human-readable order.
jsonlite does things differently. The array formats are internally consistent within each package, but not cross-compatible between them i.e. you cannot serialize an array in {yyjsonr}
and re-create it exactly using jsonlite.
The matrix handling in {yyjsonr}
is compatible with the expectationf os GeoJSON coordinate handling.
# A simple 3D array
mat <- array(1:12, dim = c(2,3,2))
mat
#> , , 1
#>
#> [,1] [,2] [,3]
#> [1,] 1 3 5
#> [2,] 2 4 6
#>
#> , , 2
#>
#> [,1] [,2] [,3]
#> [1,] 7 9 11
#> [2,] 8 10 12
# jsonlite's serialization of matrices is internally consistent and re-parses
# to the initial matrix.
str <- jsonlite::toJSON(mat, pretty = TRUE)
cat(str)
#> [
#> [
#> [1, 7],
#> [3, 9],
#> [5, 11]
#> ],
#> [
#> [2, 8],
#> [4, 10],
#> [6, 12]
#> ]
#> ]
jsonlite::fromJSON(str)
#> , , 1
#>
#> [,1] [,2] [,3]
#> [1,] 1 3 5
#> [2,] 2 4 6
#>
#> , , 2
#>
#> [,1] [,2] [,3]
#> [1,] 7 9 11
#> [2,] 8 10 12
# yyjsonr's serialization of matrices is internally consistent and re-parses
# to the initial matrix.
# But note that it is *different* to what jsonlite does.
str <- yyjsonr::to_json_str(mat, pretty = TRUE)
cat(str)
#> [
#> [
#> [
#> 1,
#> 3,
#> 5
#> ],
#> [
#> 2,
#> 4,
#> 6
#> ]
#> ],
#> [
#> [
#> 7,
#> 9,
#> 11
#> ],
#> [
#> 8,
#> 10,
#> 12
#> ]
#> ]
#> ]
yyjsonr::from_json_str(str)
#> , , 1
#>
#> [,1] [,2] [,3]
#> [1,] 1 3 5
#> [2,] 2 4 6
#>
#> , , 2
#>
#> [,1] [,2] [,3]
#> [1,] 7 9 11
#> [2,] 8 10 12