Skip to content

$output function (x, options) { hook.t(x, options[[paste0(“attr.”, class)]], options[[paste0(“class.”, class)]]) } <bytecode: 0x5571f6d28f80> <environment: 0x5571f77c03b8>

Introduction

Often we can use the corresponding base R function as a baseline. We also compare to the fansi package, where it is possible.

Data

In cli the typical use case is short string scalars, but we run some benchmarks longer strings and string vectors as well.

library(cli)
library(fansi)
options(cli.unicode = TRUE)
options(cli.num_colors = 256)
ansi <- format_inline(
  "{col_green(symbol$tick)} {.code print(x)} {.emph emphasised}"
)
plain <- ansi_strip(ansi)
vec_plain <- rep(plain, 100)
vec_ansi <- rep(ansi, 100)
vec_plain6 <- rep(plain, 6)
vec_ansi6 <- rep(plain, 6)
txt_plain <- paste(vec_plain, collapse = " ")
txt_ansi <- paste(vec_ansi, collapse = " ")
uni <- paste(
  "\U0001f477\u200d\u2640\ufe0f",
  "\U0001f477\U0001f3fb",
  "\U0001f477\u200d\u2640\ufe0f",
  "\U0001f477\U0001f3fb",
  "\U0001f477\U0001f3ff\u200d\u2640\ufe0f"
)
vec_uni <- rep(uni, 100)
txt_uni <- paste(vec_uni, collapse = " ")

ANSI functions

ansi_align()

bench::mark(
  ansi  = ansi_align(ansi, width = 20),
  plain = ansi_align(plain, width = 20), 
  base  = format(plain, width = 20),
  check = FALSE
)
#> # A tibble: 3 × 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 ansi         77.4µs   88.5µs    10436.    79.1KB     10.3
#> 2 plain        77.4µs   88.2µs    10381.        0B     10.4
#> 3 base         19.3µs   21.8µs    41398.    48.4KB     12.4
bench::mark(
  ansi  = ansi_align(ansi, width = 20, align = "right"),
  plain = ansi_align(plain, width = 20, align = "right"), 
  base  = format(plain, width = 20, justify = "right"),
  check = FALSE
)
#> # A tibble: 3 × 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 ansi         80.9µs   91.9µs    10237.        0B     14.8
#> 2 plain        82.6µs   89.4µs    10432.        0B     12.6
#> 3 base         22.9µs   25.4µs    37365.        0B     15.0

ansi_chartr()

bench::mark(
  ansi  = ansi_chartr("abc", "XYZ", ansi),
  plain = ansi_chartr("abc", "XYZ", plain),
  base  = chartr("abc", "XYZ", plain),
  check = FALSE
)
#> # A tibble: 3 × 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 ansi        201.8µs  214.6µs     4401.   75.06KB     8.34
#> 2 plain       162.5µs    173µs     5418.    8.73KB     8.28
#> 3 base          2.6µs    2.8µs   326406.        0B    32.6

ansi_columns()

bench::mark(
  ansi  = ansi_columns(vec_ansi6, width = 120),
  plain = ansi_columns(vec_plain6, width = 120),
  check = FALSE
)
#> # A tibble: 2 × 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 ansi          578µs    628µs     1540.   33.19KB     12.7
#> 2 plain         577µs    630µs     1521.    1.09KB     10.5

ansi_has_any()

bench::mark(
  cli_ansi        = ansi_has_any(ansi),
  fansi_ansi      = has_sgr(ansi),
  cli_plain       = ansi_has_any(plain),
  fansi_plain     = has_sgr(plain),
  cli_vec_ansi    = ansi_has_any(vec_ansi),
  fansi_vec_ansi  = has_sgr(vec_ansi),
  cli_vec_plain   = ansi_has_any(vec_plain),
  fansi_vec_plain = has_sgr(vec_plain),
  cli_txt_ansi    = ansi_has_any(txt_ansi),
  fansi_txt_ansi  = has_sgr(txt_ansi),
  cli_txt_plain   = ansi_has_any(txt_plain),
  fansi_txt_plain = has_sgr(vec_plain),
  check = FALSE
)
#> # A tibble: 12 × 6
#>    expression           min   median `itr/sec` mem_alloc `gc/sec`
#>    <bch:expr>      <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#>  1 cli_ansi             7µs    8.9µs   105588.    8.02KB     21.1
#>  2 fansi_ansi        51.1µs     58µs    16118.    4.18KB     12.6
#>  3 cli_plain            7µs    9.2µs   101741.        0B     20.4
#>  4 fansi_plain       52.5µs   56.9µs    16402.      688B     14.9
#>  5 cli_vec_ansi         9µs   11.2µs    78513.      448B     15.7
#>  6 fansi_vec_ansi    66.9µs   72.5µs    12616.    5.02KB     12.8
#>  7 cli_vec_plain       10µs   11.9µs    79573.      448B     15.9
#>  8 fansi_vec_plain   65.7µs   73.8µs    12355.    5.02KB     10.6
#>  9 cli_txt_ansi       7.1µs    9.4µs    94168.        0B     18.8
#> 10 fansi_txt_ansi    52.8µs   59.9µs    15625.      688B     15.0
#> 11 cli_txt_plain      7.8µs     10µs    91059.        0B     18.2
#> 12 fansi_txt_plain   63.1µs   69.4µs    13469.    5.02KB     12.6

ansi_html()

This is typically used with longer text.

bench::mark(
  cli   = ansi_html(txt_ansi),
  fansi = sgr_to_html(txt_ansi, classes = TRUE),
  check = FALSE
)
#> # A tibble: 2 × 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 cli          91.4µs    100µs     9157.      22KB     6.14
#> 2 fansi       181.1µs    202µs     4805.    55.4KB     4.07

ansi_nchar()

bench::mark(
  cli_ansi        = ansi_nchar(ansi),
  fansi_ansi      = nchar_sgr(ansi),
  base_ansi       = nchar(ansi),
  cli_plain       = ansi_nchar(plain),
  fansi_plain     = nchar_sgr(plain),
  base_plain      = nchar(plain),
  cli_vec_ansi    = ansi_nchar(vec_ansi),
  fansi_vec_ansi  = nchar_sgr(vec_ansi),
  base_vec_ansi   = nchar(vec_ansi),
  cli_vec_plain   = ansi_nchar(vec_plain),
  fansi_vec_plain = nchar_sgr(vec_plain),
  base_vec_plain  = nchar(vec_plain),
  cli_txt_ansi    = ansi_nchar(txt_ansi),
  fansi_txt_ansi  = nchar_sgr(txt_ansi),
  base_txt_ansi   = nchar(txt_ansi),
  cli_txt_plain   = ansi_nchar(txt_plain),
  fansi_txt_plain = nchar_sgr(txt_plain),
  base_txt_plain  = nchar(txt_plain),
  check = FALSE
)
#> # A tibble: 18 × 6
#>    expression           min   median `itr/sec` mem_alloc `gc/sec`
#>    <bch:expr>      <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#>  1 cli_ansi          10.5µs   12.7µs    70047.        0B    14.0 
#>  2 fansi_ansi       340.7µs    364µs     2563.   31.85KB     8.25
#>  3 base_ansi        999.9ns    1.1µs   856478.        0B     0   
#>  4 cli_plain         10.6µs   11.9µs    79063.        0B    15.8 
#>  5 fansi_plain      338.1µs  368.6µs     2523.      688B    10.5 
#>  6 base_plain       899.9ns      1µs   929453.        0B     0   
#>  7 cli_vec_ansi      46.8µs   51.8µs    18101.      448B     4.08
#>  8 fansi_vec_ansi   369.9µs  407.1µs     2374.    5.02KB     8.30
#>  9 base_vec_ansi     16.5µs   16.7µs    55675.      448B     0   
#> 10 cli_vec_plain     41.5µs   43.5µs    20792.      448B     4.16
#> 11 fansi_vec_plain    354µs  391.5µs     2425.    5.02KB     8.29
#> 12 base_vec_plain     9.5µs   10.4µs    89721.      448B     0   
#> 13 cli_txt_ansi      46.9µs   48.9µs    18677.        0B     4.07
#> 14 fansi_txt_ansi   360.7µs  382.9µs     2490.      688B    10.4 
#> 15 base_txt_ansi     15.3µs   15.4µs    59535.        0B     0   
#> 16 cli_txt_plain     40.2µs   41.9µs    21890.        0B     4.38
#> 17 fansi_txt_plain  346.6µs  373.4µs     2538.      688B     8.25
#> 18 base_txt_plain       9µs    9.2µs   103791.        0B    10.4
bench::mark(
  cli_ansi        = ansi_nchar(ansi, type = "width"),
  fansi_ansi      = nchar_sgr(ansi, type = "width"),
  base_ansi       = nchar(ansi, "width"),
  cli_plain       = ansi_nchar(plain, type = "width"),
  fansi_plain     = nchar_sgr(plain, type = "width"),
  base_plain      = nchar(plain, "width"),
  cli_vec_ansi    = ansi_nchar(vec_ansi, type = "width"),
  fansi_vec_ansi  = nchar_sgr(vec_ansi, type = "width"),
  base_vec_ansi   = nchar(vec_ansi, "width"),
  cli_vec_plain   = ansi_nchar(vec_plain, type = "width"),
  fansi_vec_plain = nchar_sgr(vec_plain, type = "width"),
  base_vec_plain  = nchar(vec_plain, "width"),
  cli_txt_ansi    = ansi_nchar(txt_ansi, type = "width"),
  fansi_txt_ansi  = nchar_sgr(txt_ansi, type = "width"),
  base_txt_ansi   = nchar(txt_ansi, "width"),
  cli_txt_plain   = ansi_nchar(txt_plain, type = "width"),
  fansi_txt_plain = nchar_sgr(txt_plain, type = "width"),
  base_txt_plain  = nchar(txt_plain, type = "width"),
  check = FALSE
)
#> # A tibble: 18 × 6
#>    expression           min   median `itr/sec` mem_alloc `gc/sec`
#>    <bch:expr>      <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#>  1 cli_ansi          13.7µs   15.6µs    60710.        0B    18.2 
#>  2 fansi_ansi       343.4µs  365.3µs     2609.      688B     8.26
#>  3 base_ansi          1.4µs    1.5µs   590143.        0B     0   
#>  4 cli_plain           14µs   15.4µs    61291.        0B    18.4 
#>  5 fansi_plain      340.3µs    372µs     2540.      688B     8.31
#>  6 base_plain         1.1µs    1.3µs   657591.        0B    65.8 
#>  7 cli_vec_ansi      57.6µs   60.2µs    15294.      448B     4.07
#>  8 fansi_vec_ansi     389µs  430.9µs     2233.    5.02KB     6.16
#>  9 base_vec_ansi     48.7µs   54.4µs    17494.      448B     2.02
#> 10 cli_vec_plain     51.7µs   58.9µs    15984.      448B     4.08
#> 11 fansi_vec_plain  370.4µs  403.2µs     2404.    5.02KB     8.28
#> 12 base_vec_plain    25.8µs     28µs    33325.      448B     0   
#> 13 cli_txt_ansi      57.5µs   64.8µs    14110.        0B     4.08
#> 14 fansi_txt_ansi   371.6µs    396µs     2387.      688B     8.26
#> 15 base_txt_ansi       52µs   56.6µs    15812.        0B     0   
#> 16 cli_txt_plain       52µs     60µs    14930.        0B     4.07
#> 17 fansi_txt_plain  357.4µs  405.6µs     2306.      688B     8.31
#> 18 base_txt_plain    27.9µs   28.4µs    31391.        0B     3.14

ansi_simplify()

Nothing to compare here.

bench::mark(
  cli_ansi      = ansi_simplify(ansi),
  cli_plain     = ansi_simplify(plain),
  cli_vec_ansi  = ansi_simplify(vec_ansi),
  cli_vec_plain = ansi_simplify(vec_plain),
  cli_txt_ansi  = ansi_simplify(txt_ansi),
  cli_txt_plain = ansi_simplify(txt_plain),
  check = FALSE
)
#> # A tibble: 6 × 6
#>   expression         min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr>    <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 cli_ansi          11µs   12.8µs    70788.    6.44KB    14.2 
#> 2 cli_plain        9.7µs   11.4µs    78142.        0B     7.81
#> 3 cli_vec_ansi    55.4µs   58.9µs    14943.      848B     4.07
#> 4 cli_vec_plain   15.3µs   17.3µs    51422.      848B    10.3 
#> 5 cli_txt_ansi      54µs   58.8µs    15649.        0B     2.02
#> 6 cli_txt_plain   10.8µs   12.6µs    66366.        0B    13.3

ansi_strip()

bench::mark(
  cli_ansi        = ansi_strip(ansi),
  fansi_ansi      = strip_sgr(ansi),
  cli_plain       = ansi_strip(plain),
  fansi_plain     = strip_sgr(plain),
  cli_vec_ansi    = ansi_strip(vec_ansi),
  fansi_vec_ansi  = strip_sgr(vec_ansi),
  cli_vec_plain   = ansi_strip(vec_plain),
  fansi_vec_plain = strip_sgr(vec_plain),
  cli_txt_ansi    = ansi_strip(txt_ansi),
  fansi_txt_ansi  = strip_sgr(txt_ansi),
  cli_txt_plain   = ansi_strip(txt_plain),
  fansi_txt_plain = strip_sgr(txt_plain),
  check = FALSE
)
#> # A tibble: 12 × 6
#>    expression           min   median `itr/sec` mem_alloc `gc/sec`
#>    <bch:expr>      <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#>  1 cli_ansi          18.3µs   20.9µs    44506.        0B    17.8 
#>  2 fansi_ansi        45.2µs   51.9µs    17632.      688B    14.9 
#>  3 cli_plain         18.1µs   20.7µs    41717.        0B    12.5 
#>  4 fansi_plain       46.4µs   51.9µs    16776.      688B    14.8 
#>  5 cli_vec_ansi      30.6µs   33.5µs    27364.      848B    11.0 
#>  6 fansi_vec_ansi      86µs   94.5µs     9569.    5.41KB     7.35
#>  7 cli_vec_plain     22.1µs   25.4µs    35633.      848B    14.3 
#>  8 fansi_vec_plain   60.6µs   69.6µs    13148.    4.59KB    10.5 
#>  9 cli_txt_ansi      29.7µs   34.4µs    27390.        0B     8.22
#> 10 fansi_txt_ansi    70.9µs   81.5µs    11759.    5.12KB    10.5 
#> 11 cli_txt_plain       18µs   21.2µs    43818.        0B    17.5 
#> 12 fansi_txt_plain   47.3µs   52.4µs    17734.      688B    14.8

ansi_strsplit()

bench::mark(
  cli_ansi        = ansi_strsplit(ansi, "i"),
  fansi_ansi      = strsplit_sgr(ansi, "i"),
  base_ansi       = strsplit(ansi, "i"),
  cli_plain       = ansi_strsplit(plain, "i"),
  fansi_plain     = strsplit_sgr(plain, "i"),
  base_plain      = strsplit(plain, "i"),
  cli_vec_ansi    = ansi_strsplit(vec_ansi, "i"),
  fansi_vec_ansi  = strsplit_sgr(vec_ansi, "i"),
  base_vec_ansi   = strsplit(vec_ansi, "i"),
  cli_vec_plain   = ansi_strsplit(vec_plain, "i"),
  fansi_vec_plain = strsplit_sgr(vec_plain, "i"),
  base_vec_plain  = strsplit(vec_plain, "i"),
  cli_txt_ansi    = ansi_strsplit(txt_ansi, "i"),
  fansi_txt_ansi  = strsplit_sgr(txt_ansi, "i"),
  base_txt_ansi   = strsplit(txt_ansi, "i"),
  cli_txt_plain   = ansi_strsplit(txt_plain, "i"),
  fansi_txt_plain = strsplit_sgr(txt_plain, "i"),
  base_txt_plain  = strsplit(txt_plain, "i"),
  check = FALSE
)
#> # A tibble: 18 × 6
#>    expression           min   median `itr/sec` mem_alloc `gc/sec`
#>    <bch:expr>      <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#>  1 cli_ansi         282.5µs 319.25µs    3028.   103.35KB    10.4 
#>  2 fansi_ansi       225.1µs  263.8µs    3617.   102.16KB    10.4 
#>  3 base_ansi            8µs    8.9µs  105114.       224B     0   
#>  4 cli_plain        281.1µs  320.5µs    3001.     8.09KB    10.5 
#>  5 fansi_plain      219.6µs    248µs    3895.     9.62KB    10.4 
#>  6 base_plain           7µs    7.9µs  116999.         0B    11.7 
#>  7 cli_vec_ansi     12.02ms  12.71ms      76.7  823.77KB    17.9 
#>  8 fansi_vec_ansi     1.5ms    1.8ms     531.   846.81KB    10.9 
#>  9 base_vec_ansi    264.1µs 302.45µs    3183.     22.7KB     2.03
#> 10 cli_vec_plain    12.21ms  12.84ms      76.5  823.77KB    18.5 
#> 11 fansi_vec_plain   1.42ms   1.56ms     619.   845.98KB    13.1 
#> 12 base_vec_plain   174.4µs  187.6µs    5019.       848B     2.02
#> 13 cli_txt_ansi       5.3ms   5.58ms     177.     63.6KB     2.04
#> 14 fansi_txt_ansi    2.19ms   2.41ms     408.    35.05KB     0   
#> 15 base_txt_ansi    234.7µs  261.2µs    3682.    18.47KB     0   
#> 16 cli_txt_plain     3.53ms   3.96ms     252.     63.6KB     2.03
#> 17 fansi_txt_plain 783.71µs 894.91µs    1096.     30.6KB     2.02
#> 18 base_txt_plain   144.4µs  168.3µs    5877.    11.05KB     2.02

ansi_strtrim()

bench::mark(
  cli_ansi        = ansi_strtrim(ansi, 10),
  fansi_ansi      = strtrim_sgr(ansi, 10),
  base_ansi       = strtrim(ansi, 10),
  cli_plain       = ansi_strtrim(plain, 10),
  fansi_plain     = strtrim_sgr(plain, 10),
  base_plain      = strtrim(plain, 10),
  cli_vec_ansi    = ansi_strtrim(vec_ansi, 10),
  fansi_vec_ansi  = strtrim_sgr(vec_ansi, 10),
  base_vec_ansi   = strtrim(vec_ansi, 10),
  cli_vec_plain   = ansi_strtrim(vec_plain, 10),
  fansi_vec_plain = strtrim_sgr(vec_plain, 10),
  base_vec_plain  = strtrim(vec_plain, 10),
  cli_txt_ansi    = ansi_strtrim(txt_ansi, 10),
  fansi_txt_ansi  = strtrim_sgr(txt_ansi, 10),
  base_txt_ansi   = strtrim(txt_ansi, 10),
  cli_txt_plain   = ansi_strtrim(txt_plain, 10),
  fansi_txt_plain = strtrim_sgr(txt_plain, 10),
  base_txt_plain  = strtrim(txt_plain, 10),
  check = FALSE
)
#> # A tibble: 18 × 6
#>    expression           min   median `itr/sec` mem_alloc `gc/sec`
#>    <bch:expr>      <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#>  1 cli_ansi         141.5µs    152µs     6150.   18.68KB    12.6 
#>  2 fansi_ansi        85.6µs   93.6µs     9683.   31.45KB    14.8 
#>  3 base_ansi          1.2µs    1.3µs   721574.     4.2KB     0   
#>  4 cli_plain        138.6µs  148.9µs     6246.        0B    12.6 
#>  5 fansi_plain       84.7µs     94µs     9494.      872B    15.0 
#>  6 base_plain         1.1µs    1.2µs   732951.        0B     0   
#>  7 cli_vec_ansi     357.2µs  407.7µs     2340.   16.73KB     4.09
#>  8 fansi_vec_ansi   190.8µs  212.4µs     4469.    5.59KB     8.33
#>  9 base_vec_ansi       48µs   51.8µs    18423.      848B     0   
#> 10 cli_vec_plain    277.9µs  316.3µs     3030.   16.73KB     6.26
#> 11 fansi_vec_plain    182µs  213.3µs     4520.    5.59KB     8.35
#> 12 base_vec_plain    38.8µs   43.3µs    22529.      848B     0   
#> 13 cli_txt_ansi     155.6µs  165.5µs     5634.        0B    12.4 
#> 14 fansi_txt_ansi    84.9µs   90.6µs    10181.      872B    14.7 
#> 15 base_txt_ansi      1.2µs    1.3µs   687763.        0B     0   
#> 16 cli_txt_plain    141.4µs  157.2µs     5826.        0B    12.5 
#> 17 fansi_txt_plain   82.7µs   91.6µs    10032.      872B    12.6 
#> 18 base_txt_plain     1.1µs    1.2µs   749957.        0B    75.0

ansi_strwrap()

This function is most useful for longer text, but it is often called for short text in cli, so it makes sense to benchmark that as well.

bench::mark(
  cli_ansi        = ansi_strwrap(ansi, 30),
  fansi_ansi      = strwrap_sgr(ansi, 30),
  base_ansi       = strwrap(ansi, 30),
  cli_plain       = ansi_strwrap(plain, 30),
  fansi_plain     = strwrap_sgr(plain, 30),
  base_plain      = strwrap(plain, 30),
  cli_vec_ansi    = ansi_strwrap(vec_ansi, 30),
  fansi_vec_ansi  = strwrap_sgr(vec_ansi, 30),
  base_vec_ansi   = strwrap(vec_ansi, 30),
  cli_vec_plain   = ansi_strwrap(vec_plain, 30),
  fansi_vec_plain = strwrap_sgr(vec_plain, 30),
  base_vec_plain  = strwrap(vec_plain, 30),
  cli_txt_ansi    = ansi_strwrap(txt_ansi, 30),
  fansi_txt_ansi  = strwrap_sgr(txt_ansi, 30),
  base_txt_ansi   = strwrap(txt_ansi, 30),
  cli_txt_plain   = ansi_strwrap(txt_plain, 30),
  fansi_txt_plain = strwrap_sgr(txt_plain, 30),
  base_txt_plain  = strwrap(txt_plain, 30),
  check = FALSE
)
#> # A tibble: 18 × 6
#>    expression           min   median `itr/sec` mem_alloc `gc/sec`
#>    <bch:expr>      <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#>  1 cli_ansi        578.21µs 638.76µs    1519.         0B    10.5 
#>  2 fansi_ansi       155.4µs  180.2µs    5190.     10.3KB    12.6 
#>  3 base_ansi           65µs   74.2µs   12543.         0B    12.6 
#>  4 cli_plain        368.4µs 406.61µs    2353.         0B    10.4 
#>  5 fansi_plain      152.2µs 166.85µs    5543.       872B    12.6 
#>  6 base_plain        55.5µs   59.3µs   15888.         0B    12.5 
#>  7 cli_vec_ansi     63.71ms  63.89ms      15.7    2.48KB    47.0 
#>  8 fansi_vec_ansi   365.5µs  396.6µs    2409.     7.25KB     6.16
#>  9 base_vec_ansi     3.38ms   3.79ms     257.    48.18KB    18.4 
#> 10 cli_vec_plain    39.44ms  40.41ms      24.5    2.48KB    17.5 
#> 11 fansi_vec_plain  305.2µs  347.8µs    2719.     6.42KB     8.32
#> 12 base_vec_plain    2.44ms   2.75ms     355.     47.4KB    15.5 
#> 13 cli_txt_ansi     34.68ms  38.17ms      26.5  507.59KB     7.95
#> 14 fansi_txt_ansi   344.1µs 394.31µs    2441.     6.77KB     6.25
#> 15 base_txt_ansi     3.96ms   4.32ms     228.   582.06KB     6.39
#> 16 cli_txt_plain     3.81ms   4.22ms     234.   369.84KB     6.43
#> 17 fansi_txt_plain    273µs  294.3µs    3238.     2.51KB     8.29
#> 18 base_txt_plain    2.64ms   2.94ms     336.   367.31KB     6.37

ansi_substr()

bench::mark(
  cli_ansi        = ansi_substr(ansi, 2, 10),
  fansi_ansi      = substr_sgr(ansi, 2, 10),
  base_ansi       = substr(ansi, 2, 10),
  cli_plain       = ansi_substr(plain, 2, 10),
  fansi_plain     = substr_sgr(plain, 2, 10),
  base_plain      = substr(plain, 2, 10),
  cli_vec_ansi    = ansi_substr(vec_ansi, 2, 10),
  fansi_vec_ansi  = substr_sgr(vec_ansi, 2, 10),
  base_vec_ansi   = substr(vec_ansi, 2, 10),
  cli_vec_plain   = ansi_substr(vec_plain, 2, 10),
  fansi_vec_plain = substr_sgr(vec_plain, 2, 10),
  base_vec_plain  = substr(vec_plain, 2, 10),
  cli_txt_ansi    = ansi_substr(txt_ansi, 2, 10),
  fansi_txt_ansi  = substr_sgr(txt_ansi, 2, 10),
  base_txt_ansi   = substr(txt_ansi, 2, 10),
  cli_txt_plain   = ansi_substr(txt_plain, 2, 10),
  fansi_txt_plain = substr_sgr(txt_plain, 2, 10),
  base_txt_plain  = substr(txt_plain, 2, 10),
  check = FALSE
)
#> # A tibble: 18 × 6
#>    expression           min   median `itr/sec` mem_alloc `gc/sec`
#>    <bch:expr>      <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#>  1 cli_ansi           9.3µs     11µs    84226.   23.82KB    25.3 
#>  2 fansi_ansi       124.6µs    138µs     6773.   28.48KB    12.7 
#>  3 base_ansi          1.1µs    1.3µs   639292.        0B     0   
#>  4 cli_plain          9.1µs   11.2µs    78899.        0B    23.7 
#>  5 fansi_plain      124.1µs  141.2µs     6717.    1.98KB    12.6 
#>  6 base_plain           1µs    1.3µs   686938.        0B     0   
#>  7 cli_vec_ansi      41.9µs   46.4µs    20436.     1.7KB     6.19
#>  8 fansi_vec_ansi   178.5µs  191.6µs     4883.    8.86KB     8.35
#>  9 base_vec_ansi      8.6µs      9µs   104389.      848B     0   
#> 10 cli_vec_plain     35.2µs   37.4µs    24802.     1.7KB     7.44
#> 11 fansi_vec_plain  170.2µs  179.1µs     5227.    8.86KB    10.5 
#> 12 base_vec_plain     8.2µs    8.5µs   111887.      848B     0   
#> 13 cli_txt_ansi       9.2µs   10.8µs    84900.        0B    17.0 
#> 14 fansi_txt_ansi   123.5µs  133.1µs     6896.    1.98KB    12.6 
#> 15 base_txt_ansi      6.3µs    6.5µs   140549.        0B     0   
#> 16 cli_txt_plain     10.2µs   11.8µs    79132.        0B    15.8 
#> 17 fansi_txt_plain  121.4µs    133µs     6951.    1.98KB    14.8 
#> 18 base_txt_plain     4.3µs    4.6µs   199818.        0B     0

ansi_tolower() , ansi_toupper()

bench::mark(
  cli_ansi        = ansi_tolower(ansi),
  base_ansi       = tolower(ansi),
  cli_plain       = ansi_tolower(plain),
  base_plain      = tolower(plain),
  cli_vec_ansi    = ansi_tolower(vec_ansi),
  base_vec_ansi   = tolower(vec_ansi),
  cli_vec_plain   = ansi_tolower(vec_plain),
  base_vec_plain  = tolower(vec_plain),
  cli_txt_ansi    = ansi_tolower(txt_ansi),
  base_txt_ansi   = tolower(txt_ansi),
  cli_txt_plain   = ansi_tolower(txt_plain),
  base_txt_plain  = tolower(txt_plain),
  check = FALSE
)
#> # A tibble: 12 × 6
#>    expression          min   median `itr/sec` mem_alloc `gc/sec`
#>    <bch:expr>     <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#>  1 cli_ansi        188.5µs  202.8µs    4630.    11.85KB    10.4 
#>  2 base_ansi         1.6µs    1.7µs  568139.         0B     0   
#>  3 cli_plain       156.6µs  165.8µs    5622.     8.73KB     8.26
#>  4 base_plain        1.2µs    1.3µs  704176.         0B     0   
#>  5 cli_vec_ansi     5.64ms   6.31ms     154.   838.77KB    19.6 
#>  6 base_vec_ansi   106.2µs  114.5µs    8329.       848B     0   
#>  7 cli_vec_plain    3.24ms   3.75ms     259.    816.9KB    21.2 
#>  8 base_vec_plain   62.7µs  72.25µs   13417.       848B     0   
#>  9 cli_txt_ansi    16.36ms  16.94ms      57.8  114.42KB     4.45
#> 10 base_txt_ansi    99.2µs    100µs    9105.         0B     2.02
#> 11 cli_txt_plain  459.61µs  493.9µs    1923.    18.16KB     2.02
#> 12 base_txt_plain   58.5µs   58.9µs   15758.         0B     0

ansi_trimws()

bench::mark(
  cli_ansi        = ansi_trimws(ansi),
  base_ansi       = trimws(ansi),
  cli_plain       = ansi_trimws(plain),
  base_plain      = trimws(plain),
  cli_vec_ansi    = ansi_trimws(vec_ansi),
  base_vec_ansi   = trimws(vec_ansi),
  cli_vec_plain   = ansi_trimws(vec_plain),
  base_vec_plain  = trimws(vec_plain),
  cli_txt_ansi    = ansi_trimws(txt_ansi),
  base_txt_ansi   = trimws(txt_ansi),
  cli_txt_plain   = ansi_trimws(txt_plain),
  base_txt_plain  = trimws(txt_plain),
  check = FALSE
)
#> # A tibble: 12 × 6
#>    expression          min   median `itr/sec` mem_alloc `gc/sec`
#>    <bch:expr>     <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#>  1 cli_ansi        130.1µs  140.7µs     6684.        0B    12.5 
#>  2 base_ansi        28.9µs   32.7µs    28535.        0B    11.4 
#>  3 cli_plain       132.5µs  142.1µs     6635.        0B    12.6 
#>  4 base_plain       29.1µs   32.9µs    27659.        0B    11.1 
#>  5 cli_vec_ansi    264.3µs  278.7µs     3352.     7.2KB     6.16
#>  6 base_vec_ansi     101µs  109.9µs     8491.    1.66KB     4.07
#>  7 cli_vec_plain   246.8µs  260.8µs     3575.     7.2KB     6.17
#>  8 base_vec_plain   90.9µs  101.7µs     9161.    1.66KB     4.08
#>  9 cli_txt_ansi    222.1µs    237µs     3929.        0B     6.14
#> 10 base_txt_ansi    70.5µs   73.9µs    12261.        0B     6.16
#> 11 cli_txt_plain   200.5µs  222.2µs     4183.        0B     6.14
#> 12 base_txt_plain   60.1µs   66.1µs    14172.        0B     6.14

UTF-8 functions

utf8_nchar()

bench::mark(
  cli        = utf8_nchar(uni, type = "chars"),
  base       = nchar(uni, "chars"),
  cli_vec    = utf8_nchar(vec_uni, type = "chars"),
  base_vec   = nchar(vec_uni, "chars"),
  cli_txt    = utf8_nchar(txt_uni, type = "chars"),
  base_txt   = nchar(txt_uni, "chars"),
  check = FALSE
)
#> # A tibble: 6 × 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 cli          13.4µs   15.3µs    61040.    12.3KB    12.2 
#> 2 base        999.9ns    1.1µs   782007.        0B    78.2 
#> 3 cli_vec      41.8µs   44.2µs    20386.      448B     4.08
#> 4 base_vec     16.9µs   17.2µs    54208.      448B     0   
#> 5 cli_txt      41.9µs   43.4µs    21578.        0B     6.48
#> 6 base_txt     16.3µs   18.4µs    51928.        0B     0
bench::mark(
  cli        = utf8_nchar(uni, type = "width"),
  base       = nchar(uni, "width"),
  cli_vec    = utf8_nchar(vec_uni, type = "width"),
  base_vec   = nchar(vec_uni, "width"),
  cli_txt    = utf8_nchar(txt_uni, type = "width"),
  base_txt   = nchar(txt_uni, "width"),
  check = FALSE
)
#> # A tibble: 6 × 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 cli          13.2µs   15.4µs    59830.        0B    18.0 
#> 2 base          1.5µs    1.7µs   533790.        0B     0   
#> 3 cli_vec      43.6µs   48.2µs    19089.      448B     4.08
#> 4 base_vec     60.8µs   62.6µs    14219.      448B     2.42
#> 5 cli_txt        44µs   48.1µs    19286.        0B     4.07
#> 6 base_txt    125.3µs  135.9µs     7107.        0B     0
bench::mark(
  cli        = utf8_nchar(uni, type = "codepoints"),
  base       = nchar(uni, "chars"),
  cli_vec    = utf8_nchar(vec_uni, type = "codepoints"),
  base_vec   = nchar(vec_uni, "chars"),
  cli_txt    = utf8_nchar(txt_uni, type = "codepoints"),
  base_txt   = nchar(txt_uni, "chars"),
  check = FALSE
)
#> # A tibble: 6 × 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 cli          14.4µs   16.5µs    56572.        0B    17.0 
#> 2 base          1.1µs    1.2µs   718048.        0B     0   
#> 3 cli_vec      31.3µs   35.8µs    25494.      448B     7.65
#> 4 base_vec     16.9µs   17.3µs    52797.      448B     5.28
#> 5 cli_txt      30.8µs     33µs    27767.        0B     5.55
#> 6 base_txt       17µs   17.5µs    50410.        0B     5.04

utf8_substr()

bench::mark(
  cli        = utf8_substr(uni, 2, 10),
  base       = substr(uni, 2, 10),
  cli_vec    = utf8_substr(vec_uni, 2, 10),
  base_vec   = substr(vec_uni, 2, 10),
  cli_txt    = utf8_substr(txt_uni, 2, 10),
  base_txt   = substr(txt_uni, 2, 10),
  check = FALSE
)
#> # A tibble: 6 × 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 cli           8.2µs   10.2µs    86814.    21.1KB    17.4 
#> 2 base          1.1µs    1.2µs   733551.        0B    73.4 
#> 3 cli_vec        45µs   47.3µs    19906.     1.7KB     4.08
#> 4 base_vec     11.6µs   12.1µs    77661.      848B     0   
#> 5 cli_txt       8.2µs    9.9µs    89463.        0B    26.8 
#> 6 base_txt      8.7µs    9.1µs   105308.        0B     0

Session info

sessioninfo::session_info()
#> ─ Session info ─────────────────────────────────────────────────────────
#>  setting  value
#>  version  R version 4.2.1 (2022-06-23)
#>  os       Ubuntu 20.04.5 LTS
#>  system   x86_64, linux-gnu
#>  ui       X11
#>  language en
#>  collate  C.UTF-8
#>  ctype    C.UTF-8
#>  tz       UTC
#>  date     2022-09-24
#>  pandoc   2.14.2 @ /usr/bin/ (via rmarkdown)
#> 
#> ─ Packages ─────────────────────────────────────────────────────────────
#>  package     * version date (UTC) lib source
#>  bench         1.1.2   2021-11-30 [1] RSPM
#>  bslib         0.4.0   2022-07-16 [1] RSPM
#>  cachem        1.0.6   2021-08-19 [1] RSPM
#>  cli         * 3.4.1   2022-09-24 [1] local
#>  codetools     0.2-18  2020-11-04 [2] CRAN (R 4.2.1)
#>  desc          1.4.2   2022-09-08 [1] RSPM
#>  digest        0.6.29  2021-12-01 [1] RSPM
#>  evaluate      0.16    2022-08-09 [1] RSPM
#>  fansi       * 1.0.3   2022-03-24 [1] RSPM
#>  fastmap       1.1.0   2021-01-25 [1] RSPM
#>  fs            1.5.2   2021-12-08 [1] RSPM
#>  glue          1.6.2   2022-02-24 [1] RSPM
#>  htmltools     0.5.3   2022-07-18 [1] RSPM
#>  jquerylib     0.1.4   2021-04-26 [1] RSPM
#>  jsonlite      1.8.0   2022-02-22 [1] RSPM
#>  knitr         1.40    2022-08-24 [1] RSPM
#>  lifecycle     1.0.2   2022-09-09 [1] RSPM
#>  magrittr      2.0.3   2022-03-30 [1] RSPM
#>  memoise       2.0.1   2021-11-26 [1] RSPM
#>  pillar        1.8.1   2022-08-19 [1] RSPM
#>  pkgconfig     2.0.3   2019-09-22 [1] RSPM
#>  pkgdown       2.0.6   2022-07-16 [1] any (@2.0.6)
#>  profmem       0.6.0   2020-12-13 [1] RSPM
#>  purrr         0.3.4   2020-04-17 [1] RSPM
#>  R6            2.5.1   2021-08-19 [1] RSPM
#>  ragg          1.2.2   2022-02-21 [1] RSPM
#>  rlang         1.0.5   2022-08-31 [1] RSPM
#>  rmarkdown     2.16    2022-08-24 [1] RSPM
#>  rprojroot     2.0.3   2022-04-02 [1] RSPM
#>  sass          0.4.2   2022-07-16 [1] RSPM
#>  sessioninfo   1.2.2   2021-12-06 [1] RSPM
#>  stringi       1.7.8   2022-07-11 [1] RSPM
#>  stringr       1.4.1   2022-08-20 [1] RSPM
#>  systemfonts   1.0.4   2022-02-11 [1] RSPM
#>  textshaping   0.3.6   2021-10-13 [1] RSPM
#>  tibble        3.1.8   2022-07-22 [1] RSPM
#>  utf8          1.2.2   2021-07-24 [1] RSPM
#>  vctrs         0.4.1   2022-04-13 [1] RSPM
#>  xfun          0.33    2022-09-12 [1] RSPM
#>  yaml          2.3.5   2022-02-21 [1] RSPM
#> 
#>  [1] /home/runner/work/_temp/Library
#>  [2] /opt/R/4.2.1/lib/R/library
#> 
#> ────────────────────────────────────────────────────────────────────────