Benchmarks

library(yyjsonr)
library(bench)
library(ggplot2)
library(tidyr)
library(ggbeeswarm)
library(geojsonsf)
library(sf)
#> Linking to GEOS 3.11.0, GDAL 3.5.3, PROJ 9.1.0; sf_use_s2() is TRUE

Benchmark overview

Validate JSON String

json_str <- write_json_str(iris)

res00 <- bench::mark(
  jsonlite     = jsonlite::validate(json_str),
  jsonify      = jsonify::validate_json(json_str),
  yyjsonr      = yyjsonr::validate_json_str(json_str),
  check = TRUE
)
#> Registered S3 method overwritten by 'jsonify':
#>   method     from    
#>   print.json jsonlite
expression min median itr/sec mem_alloc
jsonlite 99.18µs 100.53µs 9709.982 11.16KB
jsonify 49.12µs 50.1µs 19196.289 109.94KB
yyjsonr 6.89µs 7.09µs 136381.336 7.05KB

To JSON String

res01 <- bench::mark(
  jsonlite = jsonlite::toJSON(iris),
  jsonify  = jsonify::to_json(iris),
  yyjsonr  = yyjsonr::write_json_str(iris),
  check = FALSE
)
expression min median itr/sec mem_alloc
jsonlite 301.5µs 318.9µs 2979.807 152.2KB
jsonify 233.5µs 241.5µs 4086.713 25.1KB
yyjsonr 42.2µs 42.7µs 22698.813 0B

From JSON String

json_str <- write_json_str(iris)

res02 <- bench::mark(
  jsonlite     = jsonlite::fromJSON(json_str),
  jsonify      = jsonify::from_json(json_str),
  rcppsimdjson = RcppSimdJson::fparse(json_str),
  yyjsonr      = yyjsonr::read_json_str(json_str),
  check = TRUE
)
expression min median itr/sec mem_alloc
jsonlite 465.6µs 493.8µs 1993.518 427.2KB
jsonify 739.1µs 776.8µs 1274.003 36.2KB
rcppsimdjson 46.7µs 48.8µs 19985.366 106.3KB
yyjsonr 30.2µs 31.4µs 30931.149 12.1KB

From JSON raw vector

a <- nanonext::ncurl("https://postman-echo.com/get", convert = FALSE)

res03 <- bench::mark(
  jsonlite     = jsonlite::fromJSON(rawConnection(a$raw)),
  rcppsimdjson = RcppSimdJson::fparse(a$raw),
  yyjsonr      = yyjsonr::read_json_raw(a$raw),
  check = FALSE
)
expression min median itr/sec mem_alloc
jsonlite 42.39µs 45.63µs 18283.52 131.56KB
rcppsimdjson 11.11µs 11.97µs 79776.45 7.48KB
yyjsonr 1.39µs 1.56µs 608945.00 6.02KB

To JSON File

json_file <- tempfile()

res04 <- bench::mark(
  jsonlite = jsonlite::write_json(iris, json_file),
  yyjsonr  = yyjsonr::write_json_file(iris, json_file),
  check = FALSE
)
expression min median itr/sec mem_alloc
jsonlite 374.9µs 391.1µs 2530.036 48.8KB
yyjsonr 71.8µs 76.7µs 12893.705 7.05KB

From JSON File

json_file <- tempfile()
jsonlite::write_json(iris, json_file)

res05 <- bench::mark(
  jsonlite     = jsonlite::fromJSON(file(json_file)), 
  rcppsimdjson = RcppSimdJson::fload(json_file), 
  yyjsonr      = yyjsonr::read_json_file(json_file),
  check = TRUE
)
expression min median itr/sec mem_alloc
jsonlite 515.7µs 544.5µs 1813.303 116KB
rcppsimdjson 76.8µs 79.9µs 12180.592 136.4KB
yyjsonr 40.6µs 41.6µs 23408.555 12.1KB

From NDJSON file

expression min median itr/sec mem_alloc
ndjson 13.9ms 14.21ms 70.45166 3.63MB
jsonlite 21.8ms 22.01ms 45.44193 1.26MB
jsonify 12ms 12.33ms 80.89070 568.56KB
yyjsonr 994.6µs 1.05ms 870.49023 112.63KB

To NDJSON File

expression min median itr/sec mem_alloc
jsonlite 4.5ms 4.62ms 215.9953 843KB
yyjsonr 1.58ms 1.76ms 564.5970 13KB

To NDJSON String

expression min median itr/sec mem_alloc
jsonify 7.88ms 8.13ms 121.8809 308.76KB
jsonlite 6.32ms 6.61ms 147.5451 4.71MB
yyjsonr 1.37ms 1.44ms 688.8864 314.32KB

From GeoJSON String

res13 <- bench::mark(
  geojsonsf    = geojsonsf::geojson_sf(geojsonsf::geo_melbourne),
  yyjsonr      = yyjsonr::read_geojson_str(geojsonsf::geo_melbourne),
  check = FALSE
)
expression min median itr/sec mem_alloc
geojsonsf 2.74ms 2.86ms 346.5419 1.3MB
yyjsonr 259.82µs 276.77µs 3568.5088 162.5KB

To GeoJSON String

sf_obj <- sf::st_read(system.file("shape/nc.shp", package="sf"), quiet = TRUE)

res14 <- bench::mark(
  geojsonsf    = geojsonsf::sf_geojson(sf_obj),
  yyjsonr      = yyjsonr::write_geojson_str(sf_obj),
  check = FALSE
)
expression min median itr/sec mem_alloc
geojsonsf 1.23ms 1.27ms 773.6811 160KB
yyjsonr 675.88µs 724.88µs 1359.5601 487KB

Benchmark from {RcppSimdJson}

jsonfile <- system.file("jsonexamples", "twitter.json", package="RcppSimdJson")
json <- paste(readLines(jsonfile), collapse = "\n")

res09 <- bench::mark(
  jsonlite     = jsonlite::fromJSON(json),
  rcppsimdjson = RcppSimdJson::fparse(json),
  yyjsonr      = yyjsonr::read_json_str(json),
  check = FALSE
)
expression min median itr/sec mem_alloc
jsonlite 22.98ms 23.43ms 41.93077 798KB
rcppsimdjson 1.74ms 1.85ms 525.38954 182KB
yyjsonr 1.2ms 1.27ms 774.27111 214KB

Benchmark 1 from {jsonify}

n <- 1e5
df <- data.frame(
  id = 1:n
  , value = sample(letters, size = n, replace = T)
  , val2 = rnorm(n = n)
  , log = sample(c(T,F), size = n, replace = T)
  , stringsAsFactors = FALSE
)

res10 <- bench::mark(
  jsonlite = jsonlite::toJSON( df ),
  jsonify  = jsonify::to_json( df ),
  yyjsonr  = yyjsonr::write_json_str( df ),
  check = FALSE
)
#> Warning: Some expressions had a GC in every iteration; so filtering is
#> disabled.
expression min median itr/sec mem_alloc
jsonlite 59.4ms 63.6ms 15.176708 20.81MB
jsonify 114.2ms 121.8ms 8.336694 8.3MB
yyjsonr 17.6ms 17.9ms 55.606237 6.01MB

Benchmark 2 from {jsonify}

n <- 1e4
x <- list(
  x = rnorm(n = n)
  , y = list(x = rnorm(n = n))
  , z = list( list( x = rnorm(n = n)))
  , xx = rnorm(n = n)
  , yy = data.frame(
      id = 1:n
      , value = sample(letters, size = n, replace = T)
      , val2 = rnorm(n = n)
      , log = sample(c(T,F), size = n, replace = T)
    )
)

res11 <- bench::mark(
 jsonlite = jsonlite::toJSON( x ),
 jsonify  = jsonify::to_json( x ),
 yyjsonr  = yyjsonr::write_json_str(x),
 check = FALSE
)
expression min median itr/sec mem_alloc
jsonlite 10.1ms 10.47ms 92.64084 3.34MB
jsonify 13.36ms 13.82ms 72.54960 1.88MB
yyjsonr 3.31ms 3.42ms 290.55088 1.34MB

Benchmark 3 from {jsonify}

jlt <- jsonlite::toJSON( x )

res12 <- bench::mark(
  jsonlite     = jsonlite::fromJSON( jlt ),
  jsonify      = jsonify::from_json( jlt ),
  rcppsimdjson = RcppSimdJson::fparse(jlt),
  yyjsonr      = yyjsonr::read_json_str(jlt),
  check = FALSE
)
expression min median itr/sec mem_alloc
jsonlite 33.33ms 34.11ms 29.25870 2.37MB
jsonify 34.49ms 34.49ms 28.99403 1.34MB
rcppsimdjson 2.32ms 2.43ms 408.75445 593.84KB
yyjsonr 1.88ms 1.98ms 503.43348 547.25KB

Summary

#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union