Glue is advertised as

Fast, dependency free string literals

So what do we mean when we say that glue is fast. This does not mean glue is the fastest thing to use in all cases, however for the features it provides we can confidently say it is fast.

A good way to determine this is to compare it’s speed of execution to some alternatives.

Simple concatenation

bar <- "baz"

simple <-
  microbenchmark::microbenchmark(
  glue = glue::glue("foo{bar}"),
  gstring = R.utils::gstring("foo${bar}"),
  paste0 = paste0("foo", bar),
  sprintf = sprintf("foo%s", bar),
  str_interp = stringr::str_interp("foo${bar}"),
  rprintf = rprintf::rprintf("foo$bar", bar = bar)
)

print(unit = "eps", order = "median", signif = 4, simple)
#> Unit: evaluations per second
#>        expr       min     lq       mean median     uq     max neval cld
#>     rprintf 2.750e+02   1613   1798.508   1891   1990    2249   100 a  
#>     gstring 5.935e+00   2103   2293.898   2414   2561    2871   100 a  
#>  str_interp 9.535e+01   2626   2895.694   3098   3325    3887   100 a  
#>        glue 3.941e+02   6228   6576.499   6851   7356    8557   100 a  
#>     sprintf 2.111e+05 365200 536879.026 423800 621500 1531000   100   c
#>      paste0 1.443e+05 277200 408745.373 425500 500700  747400   100  b

plot_comparison(simple)

While glue() is slower than paste0,sprintf() it is twice as fast as str_interp() and gstring(), and on par with rprintf().

paste0(), sprintf() don’t do string interpolation and will likely always be significantly faster than glue, glue was never meant to be a direct replacement for them.

rprintf() does only variable interpolation, not arbitrary expressions, which was one of the explicit goals of writing glue.

So glue is ~2x as fast as the two functions (str_interp(), gstring()) which do have roughly equivalent functionality.

It also is still quite fast, with over 6000 evaluations per second on this machine.

Vectorized performance

Taking advantage of glue’s vectorization is the best way to avoid performance. For instance the vectorized form of the previous benchmark is able to generate 100,000 strings in only 22ms with performance much closer to that of paste0() and sprintf(). NB. str_interp() does not support vectorization, so were removed.

bar <- rep("bar", 1e5)

vectorized <-
  microbenchmark::microbenchmark(
  glue = glue::glue("foo{bar}"),
  gstring = R.utils::gstring("foo${bar}"),
  paste0 = paste0("foo", bar),
  sprintf = sprintf("foo%s", bar),
  rprintf = rprintf::rprintf("foo$bar", bar = bar)
)

print(unit = "ms", order = "median", signif = 4, vectorized)
#> Unit: milliseconds
#>     expr   min    lq     mean median    uq    max neval  cld
#>   paste0 12.86 13.67 14.45596  14.20 15.00  17.97   100 a   
#>     glue 14.12 15.42 17.11361  16.49 18.88  22.83   100  b  
#>  sprintf 16.80 17.91 18.92630  18.65 19.76  23.70   100  b  
#>  gstring 25.76 28.02 29.07987  28.83 30.12  34.55   100   c 
#>  rprintf 59.91 68.25 71.52097  70.21 72.87 196.90   100    d

plot_comparison(vectorized, log = FALSE)


  1. pystr is no longer available from CRAN due to failure to correct installation errors and was therefore removed from futher testing.