Some simple examples to compare behavior and performance of JSON packages in R.
-all.equal(mtcars, rjson::fromJSON(rjson::toJSON(mtcars)))
-[1] "Attributes: < names for target but not for current >"
-[2] "Attributes: < Length mismatch: comparison on first 0 components >"
-all.equal(mtcars, RJSONIO::fromJSON(RJSONIO::toJSON(mtcars)))
-[1] "Attributes: < names for target but not for current >"
-[2] "Attributes: < Length mismatch: comparison on first 0 components >"
-all.equal(mtcars, jsonlite::fromJSON(jsonlite::toJSON(mtcars)))
-[1] TRUE
-(x <- matrix(1:6, 2))
- [,1] [,2] [,3]
-[1,] 1 3 5
-[2,] 2 4 6
-rjson::fromJSON(rjson::toJSON(x))
-[1] 1 2 3 4 5 6
-RJSONIO::fromJSON(RJSONIO::toJSON(x))
-[[1]]
-[1] 1 3 5
-
-[[2]]
-[1] 2 4 6
-jsonlite::fromJSON(jsonlite::toJSON(x))
- [,1] [,2] [,3]
-[1,] 1 3 5
-[2,] 2 4 6
-x <- list(foo = 123, bar= 456)
-rjson::fromJSON(rjson::toJSON(x))
-$foo
-[1] 123
-
-$bar
-[1] 456
-RJSONIO::fromJSON(RJSONIO::toJSON(x))
-foo bar
-123 456
-jsonlite::fromJSON(jsonlite::toJSON(x))
-$foo
-[1] 123
-
-$bar
-[1] 456
-rjson::fromJSON(rjson::toJSON(c(1,2,NA,4)))
-[[1]]
-[1] 1
-
-[[2]]
-[1] 2
-
-[[3]]
-[1] "NA"
-
-[[4]]
-[1] 4
-RJSONIO::fromJSON(RJSONIO::toJSON(c(1,2,NA,4)))
-[[1]]
-[1] 1
-
-[[2]]
-[1] 2
-
-[[3]]
-NULL
-
-[[4]]
-[1] 4
-jsonlite::fromJSON(jsonlite::toJSON(c(1,2,NA,4)))
-[1] 1 2 NA 4
-x <- list("\b\f\n\r\t" = "\b\f\n\r\t")
-identical(x, rjson::fromJSON(rjson::toJSON(x)))
-[1] TRUE
-identical(x, RJSONIO::fromJSON(RJSONIO::toJSON(x)))
-[1] FALSE
-identical(x, jsonlite::fromJSON(jsonlite::toJSON(x)))
-[1] TRUE
-rjson::fromJSON('[1,2,boo",4]')
-Error: unexpected character 'b'
-RJSONIO::fromJSON('[1,2,boo",4]')
-[[1]]
-[1] 1
-
-[[2]]
-[1] 2
-
-[[3]]
-NULL
-jsonlite::fromJSON('[1,2,boo",4]')
-Error: lexical error: invalid char in json text.
- [1,2,boo",4]
- (right here) ------^
-json = '["\\u5bff\u53f8","Z\\u00fcrich", "\\u586B"]'
-rjson::fromJSON(json)
-[1] "寿司" "Zürich" "填"
-RJSONIO::fromJSON(json)
-[1] "\xff司" "Z\xfcrich" "k"
-jsonlite::fromJSON(json)
-[1] "寿司" "Zürich" "填"
-Only RJSONIO and jsonlite have functionality to validate or prettify JSON:
-x <- list(foo = c("hi", "hello"), bar=1:3)
-cat(RJSONIO::toJSON(x, pretty = TRUE))
-{
- "foo" : [
- "hi",
- "hello"
- ],
- "bar" : [
- 1,
- 2,
- 3
- ]
-}
-cat(jsonlite::toJSON(x, pretty = TRUE))
-{
- "foo": [
- "hi",
- "hello"
- ],
- "bar": [
- 1,
- 2,
- 3
- ]
-}
-RJSONIO::isValidJSON(RJSONIO::toJSON(x), asText = TRUE)
-[1] TRUE
-jsonlite::validate(jsonlite::toJSON(x))
-[1] TRUE
-RJSONIO uses significant digits, whereas jsonlite uses decimal digits. rjson does not support this.
-rjson::toJSON(pi)
-[1] "3.14159265358979"
-RJSONIO::toJSON(pi, digits=4)
-[1] "[ 3.142 ]"
-jsonlite::toJSON(pi, digits=4)
-[3.1416]
-Only RJSONIO and jsonlite give control over vector simplification. rjson always simplifies if possible.
-json <- '[1,2,3,4]'
-RJSONIO::fromJSON(json)
-[1] 1 2 3 4
-RJSONIO::fromJSON(json, simplify = FALSE)
-[[1]]
-[1] 1
-
-[[2]]
-[1] 2
-
-[[3]]
-[1] 3
-
-[[4]]
-[1] 4
-jsonlite::fromJSON(json)
-[1] 1 2 3 4
-jsonlite::fromJSON(json, simplifyVector = FALSE)
-[[1]]
-[1] 1
-
-[[2]]
-[1] 2
-
-[[3]]
-[1] 3
-
-[[4]]
-[1] 4
-rjson::fromJSON(json)
-[1] 1 2 3 4
-Comparing performance is a bit difficult because different packages do different things. The rjson
package has no options to control conversion, so the only way to benchmark common functionality is by trying to mimic rjson
:
library(microbenchmark)
-data(diamonds, package="ggplot2")
-microbenchmark(
- rjson::toJSON(diamonds),
- RJSONIO::toJSON(diamonds),
- jsonlite::toJSON(diamonds, dataframe = "column"),
- times = 10
-)
-Unit: milliseconds
- expr min lq median uq max neval
- rjson::toJSON(diamonds) 291.3 291.9 303.2 321.1 368.3 10
- RJSONIO::toJSON(diamonds) 834.8 850.3 881.1 892.4 973.5 10
- jsonlite::toJSON(diamonds, dataframe = "column") 314.8 318.5 333.7 350.5 375.5 10
-What if we throw some missing values in the mix:
-diamonds2 <- diamonds
-diamonds2[1,] <- NA;
-microbenchmark(
- rjson::toJSON(diamonds2),
- RJSONIO::toJSON(diamonds2),
- jsonlite::toJSON(diamonds2, dataframe = "column"),
- times = 10
-)
-Unit: milliseconds
- expr min lq median uq max neval
- rjson::toJSON(diamonds2) 291.4 292.2 293.8 295.1 301.0 10
- RJSONIO::toJSON(diamonds2) 1482.6 1521.9 1544.2 1564.8 1597.6 10
- jsonlite::toJSON(diamonds2, dataframe = "column") 314.0 317.9 321.4 330.0 397.6 10
-For parsing, comparing performance gets even trickier because rjson does not give any control over simplification. The following settings in RJSONIO and jsonlite are roughly equivalent to rjson:
-json <- rjson::toJSON(diamonds)
-microbenchmark(
- rjson::fromJSON(json),
- RJSONIO::fromJSON(json, simplifyWithNames=FALSE),
- jsonlite::fromJSON(json, simplifyDataFrame = FALSE, simplifyMatrix = FALSE),
- times = 10
-)
-Unit: milliseconds
- expr min lq median uq max neval
- rjson::fromJSON(json) 99.65 101.2 102.4 109.7 147.8 10
- RJSONIO::fromJSON(json, simplifyWithNames = FALSE) 415.56 417.8 422.3 454.6 477.1 10
- jsonlite::fromJSON(json, simplifyDataFrame = FALSE, simplifyMatrix = FALSE) 180.46 189.7 198.5 238.1 278.5 10
-