This small benchmark compares the
performance of the base64 encoding/decoding in package
base64url with the implementations in the packages base64enc
and openssl.
## Linking to: OpenSSL 3.5.5 27 Jan 2026
library(microbenchmark)
x = "plain text"
microbenchmark(
base64url = base64_urlencode(x),
base64enc = base64encode(charToRaw(x)),
openssl = base64_encode(x)
)## Unit: nanoseconds
## expr min lq mean median uq max neval
## base64url 581 631.0 952.31 746.5 851.0 20098 100
## base64enc 1592 1733.0 4054.89 1903.0 2109.5 209541 100
## openssl 13716 14196.5 16614.09 14537.5 14973.0 155050 100
x = "N0JBLlRaUTp1bi5KOW4xWStNWEJoLHRQaDZ3"
microbenchmark(
base64url = base64_urldecode(x),
base64enc = rawToChar(base64decode(x)),
openssl = rawToChar(base64_decode(x))
)## Unit: nanoseconds
## expr min lq mean median uq max neval
## base64url 561 631.0 1217.12 791.5 962.0 39855 100
## base64enc 2114 2429.5 3521.34 2745.5 3110.5 76754 100
## openssl 20799 21820.5 24351.79 22392.0 22807.5 132668 100
Here, the task has changed from encoding/decoding a single string to
processing multiple strings stored inside a character vector. First, we
create a small utility function which returns n random
strings with a random number of characters (between 1 and 32) each.
rand = function(n, min = 1, max = 32) {
chars = c(letters, LETTERS, as.character(0:9), c(".", ":", ",", "+", "-", "*", "/"))
replicate(n, paste0(sample(chars, sample(min:max, 1), replace = TRUE), collapse = ""))
}
set.seed(1)
rand(10)## [1] "*MaHQn6Yu1gKKHRGIPLtBtRNR" "MYPfxFnbSrv,mNVwCmvBVGSuE"
## [3] "qV:7YH" "aQ6zo5CxPV"
## [5] "Mx0NIQaCvBK8T-YRW73WX" "gtxY0pbV,R+sqHEITspNiXx"
## [7] "FMKlnpob,-" "qeOEJWOC:a040XDbJNK3AOo4"
## [9] "9fdI4y" "KB9tCP7,BElRzGd0xKon03XtbcLoB2/"
Only base64url is vectorized for string input, the
alternative implementations need wrappers to process character
vectors:
base64enc_encode = function(x) {
vapply(x, function(x) base64encode(charToRaw(x)), NA_character_, USE.NAMES = FALSE)
}
openssl_encode = function(x) {
vapply(x, function(x) base64_encode(x), NA_character_, USE.NAMES = FALSE)
}
base64enc_decode = function(x) {
vapply(x, function(x) rawToChar(base64decode(x)), NA_character_, USE.NAMES = FALSE)
}
openssl_decode = function(x) {
vapply(x, function(x) rawToChar(base64_decode(x)), NA_character_, USE.NAMES = FALSE)
}The following benchmark measures the runtime to encode 1000 random strings and then decode them again:
set.seed(1)
x = rand(1000)
microbenchmark(
base64url = base64_urldecode(base64_urlencode(x)),
base64enc = base64enc_decode(base64enc_encode(x)),
openssl = openssl_decode(openssl_encode(x))
)## Unit: microseconds
## expr min lq mean median uq max neval
## base64url 188.252 205.7795 243.3992 230.325 262.7855 532.634 100
## base64enc 5204.619 5295.7140 5752.3304 5353.316 5457.6005 10161.384 100
## openssl 37675.340 39688.3590 40391.4887 39976.212 40222.3960 84799.213 100