Skip to content

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

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         52.3µs   55.8µs    17750.    97.7KB     19.0
#> 2 plain        51.7µs   55.7µs    17699.        0B     19.6
#> 3 base         14.3µs   15.5µs    63586.    48.4KB     19.1
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         54.1µs     58µs    17054.        0B     21.3
#> 2 plain        54.4µs   58.1µs    16997.        0B     21.5
#> 3 base         16.8µs   18.1µs    54418.        0B     21.8

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          125µs  132.5µs     7459.   75.06KB     14.7
#> 2 plain        96.9µs  103.1µs     9581.    8.73KB     16.9
#> 3 base          2.5µs    2.6µs   367624.        0B      0

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          378µs    395µs     2508.   33.19KB     21.5
#> 2 plain         377µs    395µs     2509.    1.09KB     19.3

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.2µs      8µs   121149.    8.02KB    24.2 
#>  2 fansi_ansi          37µs   40.2µs    24485.    4.18KB    24.5 
#>  3 cli_plain          7.2µs      8µs   122211.        0B    24.4 
#>  4 fansi_plain       36.5µs   38.4µs    25038.      688B    12.5 
#>  5 cli_vec_ansi       8.8µs    9.4µs   103791.      448B    10.4 
#>  6 fansi_vec_ansi    48.6µs   51.1µs    19250.    5.02KB    10.5 
#>  7 cli_vec_plain      9.5µs   10.2µs    96475.      448B     9.65
#>  8 fansi_vec_plain   47.4µs   49.6µs    19929.    5.02KB    10.5 
#>  9 cli_txt_ansi       7.3µs    7.7µs   126306.        0B    12.6 
#> 10 fansi_txt_ansi    36.5µs   38.6µs    25400.      688B    12.7 
#> 11 cli_txt_plain      8.3µs    8.8µs   111159.        0B    11.1 
#> 12 fansi_txt_plain   47.5µs     50µs    19804.    5.02KB    10.5

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          75.2µs   77.2µs    12888.    28.8KB     6.13
#> 2 fansi       149.9µs  154.3µs     6406.    55.4KB     4.06

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           8.8µs    9.4µs   103692.        0B    10.4 
#>  2 fansi_ansi        98.5µs  104.2µs     9525.   31.85KB    10.3 
#>  3 base_ansi          900ns      1µs   919653.        0B     0   
#>  4 cli_plain          8.9µs    9.4µs   103836.        0B    10.4 
#>  5 fansi_plain         98µs  103.6µs     9562.      688B    10.3 
#>  6 base_plain         899ns      1µs   992322.        0B     0   
#>  7 cli_vec_ansi      35.1µs   36.7µs    27081.      448B     2.71
#>  8 fansi_vec_ansi   125.5µs    133µs     7414.    5.02KB     8.26
#>  9 base_vec_ansi     12.4µs   12.6µs    79046.      448B     0   
#> 10 cli_vec_plain     33.9µs   35.3µs    28135.      448B     2.81
#> 11 fansi_vec_plain  113.6µs  120.4µs     8235.    5.02KB     8.26
#> 12 base_vec_plain     7.6µs    7.8µs   126188.      448B     0   
#> 13 cli_txt_ansi      35.5µs   36.9µs    26911.        0B     2.69
#> 14 fansi_txt_ansi   114.3µs  120.4µs     8248.      688B     8.22
#> 15 base_txt_ansi     11.6µs   11.7µs    83474.        0B     0   
#> 16 cli_txt_plain     32.8µs   34.1µs    29066.        0B     2.91
#> 17 fansi_txt_plain  102.4µs  107.7µs     9178.      688B    10.5 
#> 18 base_txt_plain       7µs    7.1µs   139365.        0B     0
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          10.9µs   11.5µs    84855.        0B    17.0 
#>  2 fansi_ansi        99.8µs  105.2µs     9412.      688B     8.22
#>  3 base_ansi          1.3µs    1.5µs   641654.        0B    64.2 
#>  4 cli_plain         10.9µs   11.7µs    83752.        0B     8.38
#>  5 fansi_plain       98.8µs  104.6µs     9485.      688B    10.3 
#>  6 base_plain         1.1µs    1.3µs   733037.        0B     0   
#>  7 cli_vec_ansi      43.4µs   44.7µs    22260.      448B     2.23
#>  8 fansi_vec_ansi     135µs  142.4µs     6976.    5.02KB     8.27
#>  9 base_vec_ansi     41.8µs   42.6µs    23174.      448B     0   
#> 10 cli_vec_plain     42.5µs   43.7µs    22747.      448B     2.27
#> 11 fansi_vec_plain  122.2µs  129.1µs     7678.    5.02KB     8.26
#> 12 base_vec_plain    22.8µs     24µs    41365.      448B     0   
#> 13 cli_txt_ansi      43.8µs     45µs    22086.        0B     4.42
#> 14 fansi_txt_ansi   122.1µs  128.8µs     7700.      688B     8.22
#> 15 base_txt_ansi     44.7µs   45.6µs    21771.        0B     0   
#> 16 cli_txt_plain     41.6µs   42.8µs    23199.        0B     2.32
#> 17 fansi_txt_plain  109.6µs  115.6µs     8577.      688B     8.21
#> 18 base_txt_plain      25µs   25.9µs    38351.        0B     3.84

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         8.5µs    9.1µs   107564.        0B    10.8 
#> 2 cli_plain        8.1µs    8.6µs   113254.        0B    11.3 
#> 3 cli_vec_ansi      43µs   44.4µs    22392.      848B     2.24
#> 4 cli_vec_plain   13.1µs   13.8µs    71003.      848B     7.10
#> 5 cli_txt_ansi    40.8µs   42.3µs    23463.        0B     2.35
#> 6 cli_txt_plain    9.2µs    9.7µs   100485.        0B    10.0

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          14.4µs   15.4µs    63938.        0B    12.8 
#>  2 fansi_ansi        34.6µs   36.6µs    26931.      688B    13.5 
#>  3 cli_plain         14.4µs   15.3µs    64396.        0B    12.9 
#>  4 fansi_plain       33.8µs     36µs    27411.      688B    13.7 
#>  5 cli_vec_ansi      25.4µs   29.3µs    34357.      848B     6.87
#>  6 fansi_vec_ansi    67.5µs   70.2µs    14108.    5.41KB     7.08
#>  7 cli_vec_plain     17.5µs   18.4µs    53417.      848B    10.7 
#>  8 fansi_vec_plain   45.9µs   47.6µs    20807.    4.59KB    10.4 
#>  9 cli_txt_ansi      25.1µs   25.9µs    38099.        0B     7.62
#> 10 fansi_txt_ansi    55.4µs   57.1µs    17341.    5.12KB     8.23
#> 11 cli_txt_plain     15.4µs     16µs    62039.        0B    12.4 
#> 12 fansi_txt_plain   35.5µs   36.8µs    26899.      688B    13.5

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         162.4µs    169µs     5839.  103.35KB    10.3 
#>  2 fansi_ansi       145.1µs  153.3µs     6485.  102.16KB    10.4 
#>  3 base_ansi          5.3µs    5.6µs   175314.      224B    17.5 
#>  4 cli_plain          158µs  166.2µs     5948.    8.09KB    10.3 
#>  5 fansi_plain      143.8µs  151.7µs     6553.    9.62KB    10.4 
#>  6 base_plain         4.7µs    4.9µs   196263.        0B    19.6 
#>  7 cli_vec_ansi      8.52ms   8.79ms      114.  823.77KB    13.7 
#>  8 fansi_vec_ansi    1.36ms    1.4ms      696.  846.81KB    12.9 
#>  9 base_vec_ansi      205µs  211.4µs     4667.    22.7KB     2.05
#> 10 cli_vec_plain     8.43ms   8.69ms      115.  823.77KB    13.9 
#> 11 fansi_vec_plain   1.28ms   1.33ms      752.  845.98KB    13.2 
#> 12 base_vec_plain   147.6µs    151µs     6583.      848B     2.02
#> 13 cli_txt_ansi      4.14ms   4.24ms      236.    63.6KB     0   
#> 14 fansi_txt_ansi    1.92ms   1.94ms      514.   35.05KB     2.02
#> 15 base_txt_ansi    168.3µs  179.9µs     5558.   18.47KB     2.02
#> 16 cli_txt_plain      2.9ms   2.95ms      337.    63.6KB     0   
#> 17 fansi_txt_plain  660.8µs  674.7µs     1453.    30.6KB     2.02
#> 18 base_txt_plain   113.8µs  118.9µs     8309.   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         112.5µs  117.3µs     8432.   32.23KB    12.5 
#>  2 fansi_ansi        63.4µs   66.8µs    14766.   31.45KB    10.4 
#>  3 base_ansi          1.3µs    1.4µs   680655.     4.2KB    68.1 
#>  4 cli_plain        111.6µs    116µs     8523.        0B    10.3 
#>  5 fansi_plain       63.2µs   66.8µs    14726.      872B    12.5 
#>  6 base_plain         1.2µs    1.3µs   713411.        0B     0   
#>  7 cli_vec_ansi       274µs    282µs     3516.   16.73KB     6.18
#>  8 fansi_vec_ansi   148.7µs  153.5µs     6451.    5.59KB     6.16
#>  9 base_vec_ansi     42.3µs   43.7µs    22805.      848B     0   
#> 10 cli_vec_plain      215µs  221.1µs     4486.   16.73KB     6.31
#> 11 fansi_vec_plain  142.3µs  147.7µs     6701.    5.59KB     6.16
#> 12 base_vec_plain    36.8µs   38.8µs    25693.      848B     0   
#> 13 cli_txt_ansi     123.4µs  128.6µs     7699.        0B    10.3 
#> 14 fansi_txt_ansi    63.1µs   66.7µs    14799.      872B    12.5 
#> 15 base_txt_ansi      1.3µs    1.4µs   673184.        0B     0   
#> 16 cli_txt_plain    113.1µs  118.3µs     8375.        0B    12.5 
#> 17 fansi_txt_plain   62.5µs   64.7µs    15238.      872B    12.0 
#> 18 base_txt_plain     1.2µs    1.3µs   742370.        0B     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           380µs  392.3µs    2528.   266.69KB    10.4 
#>  2 fansi_ansi       111.9µs  115.7µs    8551.     10.3KB    12.5 
#>  3 base_ansi           45µs   46.6µs   21027.         0B    10.5 
#>  4 cli_plain        222.6µs    232µs    4278.         0B    10.3 
#>  5 fansi_plain      110.9µs  117.7µs    8416.       872B    12.5 
#>  6 base_plain          37µs   38.9µs   25441.         0B    10.2 
#>  7 cli_vec_ansi     39.06ms  39.71ms      25.3    2.48KB    21.7 
#>  8 fansi_vec_ansi   290.7µs  298.1µs    3276.     7.25KB     6.14
#>  9 base_vec_ansi     2.82ms   2.94ms     341.    48.18KB    10.7 
#> 10 cli_vec_plain     22.5ms  23.04ms      43.6    2.48KB    16.3 
#> 11 fansi_vec_plain  240.1µs  246.7µs    4017.     6.42KB     6.14
#> 12 base_vec_plain    2.05ms   2.13ms     466.     47.4KB    10.7 
#> 13 cli_txt_ansi     25.47ms  25.73ms      38.9  507.59KB     7.29
#> 14 fansi_txt_ansi   273.3µs  280.6µs    3535.     6.77KB     6.14
#> 15 base_txt_ansi     2.76ms   2.83ms     353.   582.06KB     4.15
#> 16 cli_txt_plain     2.13ms   2.18ms     455.   369.84KB     6.32
#> 17 fansi_txt_plain  215.8µs  221.8µs    4472.     2.51KB     6.15
#> 18 base_txt_plain    1.75ms    1.8ms     553.   367.31KB     6.28

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           8.5µs    9.4µs   102888.   23.82KB    20.6 
#>  2 fansi_ansi        89.6µs   94.7µs    10422.   28.48KB    10.4 
#>  3 base_ansi          1.2µs    1.3µs   726640.        0B     0   
#>  4 cli_plain          8.4µs    9.1µs   106847.        0B    21.4 
#>  5 fansi_plain       89.7µs   94.4µs    10444.    1.98KB    10.4 
#>  6 base_plain         1.1µs    1.3µs   721982.        0B    72.2 
#>  7 cli_vec_ansi      34.4µs   36.6µs    27199.     1.7KB     2.72
#>  8 fansi_vec_ansi   136.3µs  141.2µs     6979.    8.86KB     8.31
#>  9 base_vec_ansi      6.9µs    7.3µs   135542.      848B     0   
#> 10 cli_vec_plain     28.7µs     30µs    33091.     1.7KB     3.31
#> 11 fansi_vec_plain    128µs  133.2µs     7371.    8.86KB     8.44
#> 12 base_vec_plain     6.2µs    6.7µs   146746.      848B     0   
#> 13 cli_txt_ansi       8.4µs    9.2µs   105012.        0B    21.0 
#> 14 fansi_txt_ansi    90.4µs     95µs    10376.    1.98KB    10.4 
#> 15 base_txt_ansi      4.9µs      5µs   195597.        0B     0   
#> 16 cli_txt_plain      9.4µs   10.2µs    95650.        0B    19.1 
#> 17 fansi_txt_plain   90.5µs   94.6µs    10438.    1.98KB    10.4 
#> 18 base_txt_plain     3.3µs    3.5µs   281591.        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        117.1µs  125.7µs    7900.    11.85KB     9.51
#>  2 base_ansi         1.5µs    1.5µs  642031.         0B     0   
#>  3 cli_plain        93.6µs   97.1µs   10196.     8.73KB     8.22
#>  4 base_plain        1.1µs    1.2µs  823001.         0B     0   
#>  5 cli_vec_ansi     5.18ms   5.25ms     190.   838.77KB    15.6 
#>  6 base_vec_ansi    86.5µs   87.3µs   11415.       848B     0   
#>  7 cli_vec_plain    2.94ms   3.01ms     332.    816.9KB    12.9 
#>  8 base_vec_plain   50.9µs   51.4µs   19397.       848B     0   
#>  9 cli_txt_ansi    13.63ms  14.29ms      70.2  114.42KB     4.26
#> 10 base_txt_ansi    91.5µs   92.9µs   10753.         0B     0   
#> 11 cli_txt_plain   286.1µs  293.8µs    3374.    18.16KB     2.04
#> 12 base_txt_plain   49.4µs   49.9µs   19990.         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         85.7µs   89.6µs    11047.        0B    10.3 
#>  2 base_ansi        21.7µs   22.9µs    42982.        0B    12.9 
#>  3 cli_plain        85.9µs   89.6µs    11046.        0B    10.3 
#>  4 base_plain       21.6µs   22.7µs    43464.        0B    13.0 
#>  5 cli_vec_ansi    183.2µs  191.6µs     5136.     7.2KB     4.07
#>  6 base_vec_ansi    67.6µs     75µs    13178.    1.66KB     4.07
#>  7 cli_vec_plain   166.7µs  174.5µs     5667.     7.2KB     6.16
#>  8 base_vec_plain   62.8µs   69.9µs    14136.    1.66KB     4.07
#>  9 cli_txt_ansi    150.9µs  155.1µs     6398.        0B     6.11
#> 10 base_txt_ansi    44.8µs   46.1µs    21503.        0B     4.30
#> 11 cli_txt_plain   131.4µs  135.4µs     7319.        0B     8.19
#> 12 base_txt_plain   40.3µs   41.7µs    23794.        0B     4.76

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          10.6µs   11.4µs    85969.    12.3KB     8.60
#> 2 base          999ns    1.1µs   837144.        0B     0   
#> 3 cli_vec      32.1µs   33.1µs    29918.      448B     5.98
#> 4 base_vec     15.2µs   15.5µs    64027.      448B     0   
#> 5 cli_txt      31.7µs   32.8µs    30178.        0B     3.02
#> 6 base_txt     16.8µs   16.9µs    58353.        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          10.6µs   11.3µs    86849.        0B     8.69
#> 2 base          1.5µs    1.6µs   574169.        0B     0   
#> 3 cli_vec      34.3µs   35.7µs    27796.      448B     5.56
#> 4 base_vec     56.5µs   56.9µs    17528.      448B     0   
#> 5 cli_txt      34.7µs   35.6µs    27904.        0B     2.79
#> 6 base_txt    103.8µs    105µs     9507.        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          11.6µs   12.3µs    79624.        0B    15.9 
#> 2 base          999ns    1.1µs   829603.        0B     0   
#> 3 cli_vec      26.2µs   27.2µs    36316.      448B     7.26
#> 4 base_vec     15.2µs   15.5µs    64063.      448B     0   
#> 5 cli_txt      27.5µs   28.4µs    34934.        0B     3.49
#> 6 base_txt     16.8µs   16.9µs    58511.        0B     5.85

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      9µs   108282.    21.1KB    10.8 
#> 2 base          1.2µs    1.3µs   697639.        0B     0   
#> 3 cli_vec      39.2µs   40.2µs    24662.     1.7KB     4.93
#> 4 base_vec      9.8µs   10.1µs    98274.      848B     0   
#> 5 cli_txt       8.2µs    8.9µs   109076.        0B    10.9 
#> 6 base_txt      7.2µs    7.3µs   134621.        0B    13.5

Session info

sessioninfo::session_info()
#> ─ Session info ─────────────────────────────────────────────────────────
#>  setting  value
#>  version  R version 4.3.2 (2023-10-31)
#>  os       Ubuntu 22.04.3 LTS
#>  system   x86_64, linux-gnu
#>  ui       X11
#>  language en
#>  collate  C.UTF-8
#>  ctype    C.UTF-8
#>  tz       UTC
#>  date     2023-11-03
#>  pandoc   2.19.2 @ /usr/bin/ (via rmarkdown)
#> 
#> ─ Packages ─────────────────────────────────────────────────────────────
#>  package     * version date (UTC) lib source
#>  bench         1.1.3   2023-05-04 [1] RSPM
#>  bslib         0.5.1   2023-08-11 [1] RSPM
#>  cachem        1.0.8   2023-05-01 [1] RSPM
#>  cli         * 3.6.1   2023-11-03 [1] local
#>  codetools     0.2-19  2023-02-01 [3] CRAN (R 4.3.2)
#>  desc          1.4.2   2022-09-08 [1] RSPM
#>  digest        0.6.33  2023-07-07 [1] RSPM
#>  evaluate      0.22    2023-09-29 [1] RSPM
#>  fansi       * 1.0.5   2023-10-08 [1] RSPM
#>  fastmap       1.1.1   2023-02-24 [1] RSPM
#>  fs            1.6.3   2023-07-20 [1] RSPM
#>  glue          1.6.2   2022-02-24 [1] RSPM
#>  htmltools     0.5.6.1 2023-10-06 [1] RSPM
#>  jquerylib     0.1.4   2021-04-26 [1] RSPM
#>  jsonlite      1.8.7   2023-06-29 [1] RSPM
#>  knitr         1.45    2023-10-30 [1] RSPM
#>  lifecycle     1.0.3   2022-10-07 [1] RSPM
#>  magrittr      2.0.3   2022-03-30 [1] RSPM
#>  memoise       2.0.1   2021-11-26 [1] RSPM
#>  pillar        1.9.0   2023-03-22 [1] RSPM
#>  pkgconfig     2.0.3   2019-09-22 [1] RSPM
#>  pkgdown       2.0.7   2022-12-14 [1] any (@2.0.7)
#>  profmem       0.6.0   2020-12-13 [1] RSPM
#>  purrr         1.0.2   2023-08-10 [1] RSPM
#>  R6            2.5.1   2021-08-19 [1] RSPM
#>  ragg          1.2.6   2023-10-10 [1] RSPM
#>  rlang         1.1.1   2023-04-28 [1] RSPM
#>  rmarkdown     2.25    2023-09-18 [1] RSPM
#>  rprojroot     2.0.3   2022-04-02 [1] RSPM
#>  sass          0.4.7   2023-07-15 [1] RSPM
#>  sessioninfo   1.2.2   2021-12-06 [1] RSPM
#>  stringi       1.7.12  2023-01-11 [1] RSPM
#>  stringr       1.5.0   2022-12-02 [1] RSPM
#>  systemfonts   1.0.5   2023-10-09 [1] RSPM
#>  textshaping   0.3.7   2023-10-09 [1] RSPM
#>  tibble        3.2.1   2023-03-20 [1] RSPM
#>  utf8          1.2.4   2023-10-22 [1] RSPM
#>  vctrs         0.6.4   2023-10-12 [1] RSPM
#>  xfun          0.40    2023-08-09 [1] RSPM
#>  yaml          2.3.7   2023-01-23 [1] RSPM
#> 
#>  [1] /home/runner/work/_temp/Library
#>  [2] /opt/R/4.3.2/lib/R/site-library
#>  [3] /opt/R/4.3.2/lib/R/library
#> 
#> ────────────────────────────────────────────────────────────────────────