This small benchmark compares the performance of the base64 encoding/decoding in package base64url
with the implementations in the packages base64enc
and openssl
.
library(base64url)
library(base64enc)
library(openssl)
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 cld
## base64url 598 719.5 1222.75 861.5 961.5 28170 100 a
## base64enc 3252 3409.0 5345.50 3920.0 4218.0 113086 100 b
## openssl 8964 9305.5 10912.67 9465.5 9980.0 64796 100 c
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 cld
## base64url 725 833.0 1365.00 1115.5 1310.5 15764 100 a
## base64enc 4804 5177.0 7419.04 5835.0 6234.5 64962 100 b
## openssl 18412 18933.5 21839.90 19340.5 20524.5 125189 100 c
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] "zN.n9+TRe" "mVA1IX/"
## [3] "1,oSisAaA8xHP" "m5U2hXC4S2MK2bGY"
## [5] "G7EqegvJTC.uFwSrH0f8x5x" "G97A1-DXBw0"
## [7] "XiqjqeS" "13FC3PTys/RoiG:P*YyDkaXhES/IH"
## [9] "0FJopP" "fcS,PMK*JVPqrYFmZh7"
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
## base64url 215.029 222.9475 244.0447 238.1795 257.464 358.599
## base64enc 7185.749 7349.0650 7951.7801 7927.6675 8348.159 10157.637
## openssl 21620.231 22093.2525 23687.5476 22828.9190 23330.632 86346.942
## neval cld
## 100 a
## 100 b
## 100 c