Skip to content

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

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         46.9µs     50µs    19752.    97.7KB     21.2
#> 2 plain        46.5µs   49.8µs    19633.        0B     21.9
#> 3 base         12.2µs   13.3µs    73685.    48.4KB     22.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         49.1µs   52.2µs    18650.        0B     23.6
#> 2 plain        47.8µs   51.4µs    19079.        0B     23.5
#> 3 base         14.3µs   15.6µs    63067.        0B     25.2

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       109.87µs    116µs     8491.   75.06KB     16.9
#> 2 plain       87.33µs   92.5µs    10617.    8.73KB     16.9
#> 3 base         1.86µs      2µs   479604.        0B     48.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          349µs    365µs     2708.   33.19KB     21.5
#> 2 plain         349µs    365µs     2706.    1.09KB     21.4

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          5.49µs   5.96µs   162780.    8.02KB     48.8
#>  2 fansi_ansi       30.73µs  33.69µs    28732.    4.18KB     20.1
#>  3 cli_plain         5.49µs   5.87µs   156403.        0B     15.6
#>  4 fansi_plain      30.81µs  32.75µs    29664.      688B     14.8
#>  5 cli_vec_ansi      6.97µs   7.39µs   133243.      448B     13.3
#>  6 fansi_vec_ansi   39.97µs  42.18µs    23194.    5.02KB     11.6
#>  7 cli_vec_plain     7.36µs   7.84µs   125309.      448B     12.5
#>  8 fansi_vec_plain  39.42µs  41.42µs    23816.    5.02KB     14.3
#>  9 cli_txt_ansi      5.61µs   6.02µs   161553.        0B     16.2
#> 10 fansi_txt_ansi   30.99µs  32.76µs    29760.      688B     14.9
#> 11 cli_txt_plain     6.37µs   6.76µs   145795.        0B     14.6
#> 12 fansi_txt_plain  39.22µs  41.44µs    23779.    5.02KB     11.9

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          57.6µs   59.1µs    16773.    28.8KB     6.11
#> 2 fansi       124.3µs  127.3µs     7715.    55.4KB     4.05

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          7.11µs   7.75µs   126948.        0B    12.7 
#>  2 fansi_ansi       91.41µs  95.23µs    10369.   31.85KB    10.3 
#>  3 base_ansi       842.03ns 891.97ns  1037306.        0B     0   
#>  4 cli_plain         7.13µs   7.78µs   126460.        0B    12.6 
#>  5 fansi_plain      90.33µs  94.69µs    10429.      688B    10.3 
#>  6 base_plain      801.05ns  841.1ns  1097294.        0B     0   
#>  7 cli_vec_ansi     28.27µs  29.04µs    34145.      448B     6.83
#>  8 fansi_vec_ansi  111.04µs 115.02µs     8515.    5.02KB     8.25
#>  9 base_vec_ansi    12.17µs  12.25µs    80892.      448B     0   
#> 10 cli_vec_plain    27.04µs  27.88µs    35586.      448B     3.56
#> 11 fansi_vec_plain 101.37µs 105.38µs     9296.    5.02KB    10.3 
#> 12 base_vec_plain    7.31µs   7.39µs   134023.      448B     0   
#> 13 cli_txt_ansi     28.37µs  29.13µs    34063.        0B     3.41
#> 14 fansi_txt_ansi  102.48µs 107.32µs     9196.      688B     8.20
#> 15 base_txt_ansi    11.61µs  11.73µs    84667.        0B     0   
#> 16 cli_txt_plain    26.61µs  27.34µs    36218.        0B     7.25
#> 17 fansi_txt_plain   92.6µs  97.51µs    10108.      688B    10.3 
#> 18 base_txt_plain    6.89µs   6.94µs   140835.        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          8.72µs   9.49µs   103456.        0B    10.3 
#>  2 fansi_ansi       91.45µs  95.72µs    10327.      688B    10.3 
#>  3 base_ansi         1.14µs   1.18µs   808171.        0B    80.8 
#>  4 cli_plain         8.72µs   9.43µs   104120.        0B    10.4 
#>  5 fansi_plain      90.87µs  95.34µs    10357.      688B    10.3 
#>  6 base_plain      961.01ns      1µs   934727.        0B     0   
#>  7 cli_vec_ansi     33.91µs  34.72µs    28565.      448B     5.71
#>  8 fansi_vec_ansi  117.21µs 121.61µs     8114.    5.02KB     8.24
#>  9 base_vec_ansi    35.57µs  35.79µs    27777.      448B     0   
#> 10 cli_vec_plain    32.93µs  33.86µs    29287.      448B     2.93
#> 11 fansi_vec_plain 107.92µs 112.05µs     8811.    5.02KB    10.4 
#> 12 base_vec_plain   18.48µs  18.67µs    53283.      448B     0   
#> 13 cli_txt_ansi     34.41µs  35.13µs    28261.        0B     2.83
#> 14 fansi_txt_ansi  108.89µs 114.02µs     8646.      688B    10.4 
#> 15 base_txt_ansi    38.08µs  38.28µs    25656.        0B     0   
#> 16 cli_txt_plain     32.7µs   33.6µs    28043.        0B     2.80
#> 17 fansi_txt_plain  99.88µs 104.44µs     9421.      688B    10.3 
#> 18 base_txt_plain   20.41µs  20.63µs    48213.        0B     0

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        6.94µs   7.51µs   130471.        0B    13.0 
#> 2 cli_plain       6.43µs   7.04µs   139374.        0B    13.9 
#> 3 cli_vec_ansi   32.97µs   33.9µs    29189.      848B     2.92
#> 4 cli_vec_plain  10.33µs  11.01µs    89627.      848B     8.96
#> 5 cli_txt_ansi   32.44µs  33.22µs    29900.        0B     2.99
#> 6 cli_txt_plain   7.31µs   7.93µs   123697.        0B    12.4

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          11.6µs   12.3µs    79495.        0B    23.9 
#>  2 fansi_ansi        29.1µs   30.9µs    31871.      688B    12.8 
#>  3 cli_plain         11.4µs   12.1µs    81383.        0B    16.3 
#>  4 fansi_plain       28.4µs   29.8µs    33083.      688B    16.5 
#>  5 cli_vec_ansi      20.1µs   20.9µs    46381.      848B     9.28
#>  6 fansi_vec_ansi      55µs   56.8µs    17441.    5.41KB     8.29
#>  7 cli_vec_plain     14.2µs   14.9µs    66437.      848B    13.3 
#>  8 fansi_vec_plain   37.4µs   39.1µs    25288.    4.59KB    12.7 
#>  9 cli_txt_ansi      20.1µs   20.8µs    47316.        0B     9.47
#> 10 fansi_txt_ansi    44.7µs   46.6µs    21151.    5.12KB    10.6 
#> 11 cli_txt_plain     12.4µs   13.1µs    75042.        0B    15.0 
#> 12 fansi_txt_plain   29.8µs   31.5µs    31256.      688B    15.6

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        146.79µs 151.72µs     6462.  103.34KB    12.4 
#>  2 fansi_ansi      130.34µs 136.24µs     7250.  102.16KB    12.5 
#>  3 base_ansi         4.13µs   4.45µs   221050.      224B     0   
#>  4 cli_plain       144.44µs 150.41µs     6548.    8.09KB    12.5 
#>  5 fansi_plain     126.61µs 134.42µs     7311.    9.62KB    12.6 
#>  6 base_plain        3.63µs   3.91µs   250728.        0B     0   
#>  7 cli_vec_ansi      7.36ms   7.52ms      133.  823.77KB    16.6 
#>  8 fansi_vec_ansi    1.07ms   1.11ms      880.  846.81KB    15.1 
#>  9 base_vec_ansi   156.92µs 163.56µs     6021.    22.7KB     4.13
#> 10 cli_vec_plain     7.29ms   7.45ms      133.  823.77KB    13.7 
#> 11 fansi_vec_plain   1.01ms   1.05ms      948.  845.98KB    17.6 
#> 12 base_vec_plain  108.06µs 110.84µs     8852.      848B     4.06
#> 13 cli_txt_ansi      3.24ms   3.29ms      287.    63.6KB     0   
#> 14 fansi_txt_ansi    1.53ms   1.56ms      632.   35.05KB     2.02
#> 15 base_txt_ansi   137.37µs 145.18µs     6842.   18.47KB     2.03
#> 16 cli_txt_plain     2.39ms   2.44ms      406.    63.6KB     0   
#> 17 fansi_txt_plain 513.02µs  531.4µs     1869.    30.6KB     2.02
#> 18 base_txt_plain    91.2µs  93.16µs    10549.   11.05KB     4.07

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        100.51µs 104.03µs     9439.   32.23KB    12.4 
#>  2 fansi_ansi       53.81µs  57.34µs    16932.   31.45KB    15.0 
#>  3 base_ansi         1.04µs   1.09µs   884842.     4.2KB     0   
#>  4 cli_plain        98.06µs 101.37µs     9714.        0B    12.4 
#>  5 fansi_plain      53.52µs  57.04µs    17246.      872B    14.6 
#>  6 base_plain      981.96ns   1.03µs   919230.        0B     0   
#>  7 cli_vec_ansi    222.78µs 227.95µs     4342.   16.73KB     6.16
#>  8 fansi_vec_ansi  121.11µs 124.77µs     7861.    5.59KB     7.06
#>  9 base_vec_ansi    33.93µs  34.21µs    29067.      848B     2.91
#> 10 cli_vec_plain   180.24µs 183.75µs     5386.   16.73KB     6.17
#> 11 fansi_vec_plain 117.64µs 120.26µs     8230.    5.59KB     8.27
#> 12 base_vec_plain   29.08µs  29.41µs    33282.      848B     0   
#> 13 cli_txt_ansi    107.18µs 110.36µs     8949.        0B    12.4 
#> 14 fansi_txt_ansi    53.1µs  55.69µs    17670.      872B    14.7 
#> 15 base_txt_ansi      1.1µs   1.15µs   829256.        0B     0   
#> 16 cli_txt_plain    99.23µs 102.68µs     9626.        0B    12.4 
#> 17 fansi_txt_plain  52.97µs  56.67µs    17415.      872B    14.6 
#> 18 base_txt_plain    1.01µs   1.07µs   877232.        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        332.16µs  341.5µs    2878.   266.69KB    12.5 
#>  2 fansi_ansi       97.08µs 102.32µs    9608.     10.3KB    14.6 
#>  3 base_ansi        39.66µs   41.9µs   23431.         0B    11.7 
#>  4 cli_plain       203.26µs 210.74µs    4664.         0B    10.3 
#>  5 fansi_plain      96.24µs 101.99µs    9573.       872B    14.8 
#>  6 base_plain       32.84µs  34.52µs   28552.         0B    11.4 
#>  7 cli_vec_ansi     33.95ms  34.95ms      25.8    2.48KB    22.1 
#>  8 fansi_vec_ansi   240.6µs 246.02µs    3958.     7.25KB     6.15
#>  9 base_vec_ansi     2.26ms   2.32ms     425.    48.18KB    15.2 
#> 10 cli_vec_plain     20.7ms   20.9ms      47.8    2.48KB    15.9 
#> 11 fansi_vec_plain 202.57µs 207.81µs    4745.     6.42KB     8.25
#> 12 base_vec_plain    1.65ms    1.7ms     588.     47.4KB    12.8 
#> 13 cli_txt_ansi     20.82ms  21.02ms      46.7  507.59KB     9.84
#> 14 fansi_txt_ansi  228.03µs 233.28µs    4241.     6.77KB     6.13
#> 15 base_txt_ansi     2.07ms   2.11ms     471.   582.06KB     6.39
#> 16 cli_txt_plain     1.65ms   1.68ms     589.   369.84KB     8.63
#> 17 fansi_txt_plain 182.85µs 188.11µs    5208.     2.51KB     6.15
#> 18 base_txt_plain    1.33ms   1.36ms     727.   367.31KB     8.60

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          6.39µs   6.86µs   142409.   23.82KB    28.5 
#>  2 fansi_ansi       76.12µs   79.3µs    12429.   28.48KB    12.5 
#>  3 base_ansi         1.01µs   1.06µs   894204.        0B     0   
#>  4 cli_plain         6.41µs   6.92µs   141956.        0B    28.4 
#>  5 fansi_plain       75.7µs  78.86µs    12379.    1.98KB    12.5 
#>  6 base_plain      961.94ns   1.01µs   934747.        0B     0   
#>  7 cli_vec_ansi     26.79µs  27.72µs    35844.     1.7KB     7.17
#>  8 fansi_vec_ansi  112.69µs 116.73µs     8389.    8.86KB     8.42
#>  9 base_vec_ansi      5.7µs   6.65µs   146531.      848B     0   
#> 10 cli_vec_plain    22.61µs  23.48µs    42181.     1.7KB     8.44
#> 11 fansi_vec_plain 108.16µs 112.76µs     8657.    8.86KB     8.31
#> 12 base_vec_plain    5.34µs   6.21µs   159032.      848B     0   
#> 13 cli_txt_ansi      6.48µs   7.07µs   137047.        0B    27.4 
#> 14 fansi_txt_ansi   77.57µs  81.58µs    12072.    1.98KB    12.5 
#> 15 base_txt_ansi     3.84µs    3.9µs   250902.        0B     0   
#> 16 cli_txt_plain     7.22µs   7.88µs   118454.        0B    23.7 
#> 17 fansi_txt_plain  76.81µs  81.51µs    12135.    1.98KB    12.5 
#> 18 base_txt_plain    2.63µs   2.69µs   362058.        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       104.33µs 108.34µs    9104.    11.85KB    10.4 
#>  2 base_ansi        1.29µs   1.35µs  720008.         0B     0   
#>  3 cli_plain       84.09µs   87.7µs   11267.     8.73KB    10.3 
#>  4 base_plain          1µs   1.03µs  948166.         0B     0   
#>  5 cli_vec_ansi     4.02ms   4.13ms     239.   838.77KB    15.6 
#>  6 base_vec_ansi   72.47µs  73.91µs   13471.       848B     2.02
#>  7 cli_vec_plain    2.25ms   2.31ms     430.    816.9KB    17.7 
#>  8 base_vec_plain  43.03µs  44.21µs   22527.       848B     0   
#>  9 cli_txt_ansi    11.26ms  11.34ms      87.1  114.42KB     4.25
#> 10 base_txt_ansi   73.71µs  73.93µs   13464.         0B     0   
#> 11 cli_txt_plain  242.92µs 248.73µs    3979.    18.16KB     4.06
#> 12 base_txt_plain   41.4µs  41.61µs   23700.         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         75.4µs   79.1µs    12397.        0B    12.4 
#>  2 base_ansi        17.7µs   18.9µs    52115.        0B    15.6 
#>  3 cli_plain        74.8µs     79µs    12342.        0B    12.4 
#>  4 base_plain       17.9µs   19.1µs    51515.        0B    15.5 
#>  5 cli_vec_ansi    155.8µs  161.7µs     6098.     7.2KB     6.15
#>  6 base_vec_ansi    55.3µs   60.9µs    16229.    1.66KB     4.06
#>  7 cli_vec_plain   142.8µs  148.9µs     6552.     7.2KB     6.15
#>  8 base_vec_plain   50.8µs   55.7µs    17728.    1.66KB     4.06
#>  9 cli_txt_ansi    133.1µs  137.4µs     7168.        0B     8.28
#> 10 base_txt_ansi    36.5µs   37.7µs    26202.        0B     5.24
#> 11 cli_txt_plain   117.5µs  121.2µs     8075.        0B     8.20
#> 12 base_txt_plain   33.1µs   34.6µs    28631.        0B     8.59

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          8.54µs   9.23µs   106657.    12.3KB    10.7 
#> 2 base       862.05ns 911.07ns  1011349.        0B     0   
#> 3 cli_vec     25.29µs  26.55µs    36971.      448B     7.40
#> 4 base_vec    11.41µs  11.52µs    85943.      448B     0   
#> 5 cli_txt     26.05µs   26.9µs    36870.        0B     3.69
#> 6 base_txt    12.57µs  12.64µs    78365.        0B     7.84
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          8.41µs   9.06µs   108414.        0B    10.8 
#> 2 base         1.28µs   1.33µs   711833.        0B     0   
#> 3 cli_vec     29.07µs  29.95µs    32554.      448B     6.51
#> 4 base_vec    44.53µs  46.05µs    21560.      448B     0   
#> 5 cli_txt     29.55µs  30.65µs    32407.        0B     3.24
#> 6 base_txt    81.27µs  83.83µs    11885.        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          9.07µs   9.79µs   100389.        0B    10.0 
#> 2 base       840.98ns 882.08ns  1071942.        0B     0   
#> 3 cli_vec     19.74µs  20.53µs    47355.      448B     9.47
#> 4 base_vec    11.41µs   11.5µs    86345.      448B     0   
#> 5 cli_txt     20.89µs  21.55µs    46022.        0B     9.21
#> 6 base_txt    12.56µs  12.63µs    78534.        0B     0

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          6.22µs   6.64µs   147569.    21.1KB    14.8 
#> 2 base         1.01µs   1.05µs   910019.        0B    91.0 
#> 3 cli_vec     30.02µs  31.17µs    31387.     1.7KB     3.14
#> 4 base_vec      7.7µs   7.92µs   125225.      848B     0   
#> 5 cli_txt      6.14µs   6.55µs   149957.        0B    30.0 
#> 6 base_txt     5.46µs    5.5µs   180023.        0B     0

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-12-11
#>  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.6.1   2023-11-28 [1] RSPM
#>  cachem        1.0.8   2023-05-01 [1] RSPM
#>  cli         * 3.6.2   2023-12-11 [1] local
#>  codetools     0.2-19  2023-02-01 [3] CRAN (R 4.3.2)
#>  desc          1.4.3   2023-12-10 [1] RSPM
#>  digest        0.6.33  2023-07-07 [1] RSPM
#>  evaluate      0.23    2023-11-01 [1] RSPM
#>  fansi       * 1.0.6   2023-12-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.7   2023-11-03 [1] RSPM
#>  jquerylib     0.1.4   2021-04-26 [1] RSPM
#>  jsonlite      1.8.8   2023-12-04 [1] RSPM
#>  knitr         1.45    2023-10-30 [1] RSPM
#>  lifecycle     1.0.4   2023-11-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.2   2023-11-04 [1] RSPM
#>  rmarkdown     2.25    2023-09-18 [1] RSPM
#>  sass          0.4.8   2023-12-06 [1] RSPM
#>  sessioninfo   1.2.2   2021-12-06 [1] RSPM
#>  stringi       1.8.2   2023-11-23 [1] RSPM
#>  stringr       1.5.1   2023-11-14 [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.5   2023-12-01 [1] RSPM
#>  xfun          0.41    2023-11-01 [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
#> 
#> ────────────────────────────────────────────────────────────────────────