--- title: "Benchmark" author: "Michel Lang" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Benchmark} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r,include=FALSE,cache=FALSE} do.eval = requireNamespace("microbenchmark", quietly = TRUE) ``` This small benchmark compares the performance of the base64 encoding/decoding in package `base64url` with the implementations in the packages [`base64enc`](https://cran.r-project.org/package=base64enc) and [`openssl`](https://cran.r-project.org/package=openssl). ## Encoding of a single string ```{r, eval=do.eval} library(base64url) library(base64enc) library(openssl) library(microbenchmark) x = "plain text" microbenchmark( base64url = base64_urlencode(x), base64enc = base64encode(charToRaw(x)), openssl = base64_encode(x) ) ``` ## Decoding of a single string ```{r, eval = do.eval} x = "N0JBLlRaUTp1bi5KOW4xWStNWEJoLHRQaDZ3" microbenchmark( base64url = base64_urldecode(x), base64enc = rawToChar(base64decode(x)), openssl = rawToChar(base64_decode(x)) ) ``` ## Encoding and decoding of character vectors 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. ```{r, eval = do.eval} 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) ``` Only `base64url` is vectorized for string input, the alternative implementations need wrappers to process character vectors: ```{r, eval = do.eval} 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: ```{r, eval = do.eval} 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)) ) ```