Skip to content

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

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         45.1µs   47.8µs    20544.    98.5KB     21.0
#> 2 plain        45.1µs     48µs    20554.        0B     21.8
#> 3 base         11.5µs   12.4µs    79104.    48.4KB     23.7
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         46.9µs   50.1µs    19643.        0B     23.4
#> 2 plain        46.1µs   49.1µs    20066.        0B     25.5
#> 3 base         13.5µs   14.7µs    66980.        0B     20.1

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       110.44µs  115.8µs     8490.   75.07KB     16.8
#> 2 plain       88.66µs  92.91µs    10585.    8.73KB     16.8
#> 3 base         1.89µs   2.05µs   471978.        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          328µs    342µs     2890.   33.17KB     21.5
#> 2 plain         320µs    337µs     2891.    1.09KB     23.6

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.66µs   6.11µs   159846.    8.02KB     32.0
#>  2 fansi_ansi       30.47µs  33.12µs    29733.    4.18KB     26.8
#>  3 cli_plain         5.59µs   5.86µs   167396.        0B     33.5
#>  4 fansi_plain      30.37µs   31.9µs    30823.      688B     27.8
#>  5 cli_vec_ansi      6.91µs   7.29µs   134658.      448B     26.9
#>  6 fansi_vec_ansi   39.71µs  41.76µs    23575.    5.02KB     21.2
#>  7 cli_vec_plain     7.46µs   7.88µs   125228.      448B     12.5
#>  8 fansi_vec_plain  38.83µs  40.94µs    24084.    5.02KB     21.7
#>  9 cli_txt_ansi      5.48µs   5.88µs   166868.        0B     33.4
#> 10 fansi_txt_ansi   30.52µs  32.09µs    30293.      688B     27.3
#> 11 cli_txt_plain      6.4µs   6.78µs   145292.        0B     29.1
#> 12 fansi_txt_plain  39.15µs  41.24µs    23895.    5.02KB     21.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          61.9µs   63.1µs    15708.    28.8KB    10.3 
#> 2 fansi       122.6µs  125.3µs     7897.    55.3KB     8.24

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           6.6µs    7.1µs   137789.        0B    27.6 
#>  2 fansi_ansi        91.2µs  94.84µs    10394.   31.85KB    18.9 
#>  3 base_ansi       891.04ns 932.14ns  1000930.        0B   100.  
#>  4 cli_plain         6.55µs   7.07µs   139037.        0B    13.9 
#>  5 fansi_plain      90.16µs  94.11µs    10479.      688B    18.9 
#>  6 base_plain      821.08ns 862.05ns  1089715.        0B   109.  
#>  7 cli_vec_ansi     28.15µs  28.83µs    34420.      448B     6.89
#>  8 fansi_vec_ansi  111.29µs 115.19µs     8496.    5.02KB    14.6 
#>  9 base_vec_ansi    13.51µs   13.6µs    73082.      448B     0   
#> 10 cli_vec_plain    26.42µs   27.1µs    36521.      448B     7.31
#> 11 fansi_vec_plain 101.31µs 105.66µs     9308.    5.02KB    16.9 
#> 12 base_vec_plain    8.05µs   8.13µs   121423.      448B     0   
#> 13 cli_txt_ansi     27.67µs  28.69µs    34505.        0B     6.90
#> 14 fansi_txt_ansi  102.05µs 105.72µs     9312.      688B    16.7 
#> 15 base_txt_ansi    12.98µs  13.04µs    76071.        0B     0   
#> 16 cli_txt_plain    25.89µs  26.47µs    37409.        0B     7.48
#> 17 fansi_txt_plain  92.72µs  96.78µs    10146.      688B    19.3 
#> 18 base_txt_plain    7.69µs   7.74µs   126639.        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.29µs   8.77µs   112522.        0B    22.5 
#>  2 fansi_ansi       90.52µs  93.64µs    10496.      688B    18.9 
#>  3 base_ansi          1.2µs   1.23µs   783870.        0B     0   
#>  4 cli_plain         8.13µs    8.6µs   114432.        0B    34.3 
#>  5 fansi_plain      90.57µs  93.75µs    10500.      688B    19.0 
#>  6 base_plain        1.01µs   1.05µs   913532.        0B     0   
#>  7 cli_vec_ansi     33.99µs  34.66µs    28549.      448B     8.57
#>  8 fansi_vec_ansi  119.03µs 122.53µs     8056.    5.02KB    12.5 
#>  9 base_vec_ansi    38.12µs  38.39µs    25885.      448B     2.59
#> 10 cli_vec_plain    32.95µs  33.68µs    29422.      448B     5.89
#> 11 fansi_vec_plain 109.78µs 113.25µs     8664.    5.02KB    16.8 
#> 12 base_vec_plain   19.88µs  20.03µs    49616.      448B     0   
#> 13 cli_txt_ansi     34.31µs  34.88µs    28360.        0B     5.67
#> 14 fansi_txt_ansi  110.64µs 114.35µs     8617.      688B    16.7 
#> 15 base_txt_ansi    40.76µs  40.96µs    24274.        0B     0   
#> 16 cli_txt_plain    32.62µs   33.3µs    29719.        0B     8.92
#> 17 fansi_txt_plain   98.9µs 103.17µs     9545.      688B    16.8 
#> 18 base_txt_plain   21.82µs  22.07µs    45041.        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.53µs   7.01µs   139412.        0B    27.9 
#> 2 cli_plain       6.09µs   6.55µs   149517.        0B    29.9 
#> 3 cli_vec_ansi   33.12µs  34.06µs    29083.      848B     5.82
#> 4 cli_vec_plain  10.01µs  10.55µs    93243.      848B     9.33
#> 5 cli_txt_ansi   32.51µs  33.12µs    29965.        0B     5.99
#> 6 cli_txt_plain    6.9µs    7.4µs   132090.        0B    26.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    79549.        0B     31.8
#>  2 fansi_ansi        28.6µs   30.1µs    32468.      688B     26.0
#>  3 cli_plain         11.5µs   12.1µs    81142.        0B     32.5
#>  4 fansi_plain         28µs   29.7µs    32914.      688B     26.4
#>  5 cli_vec_ansi      20.6µs   21.7µs    45496.      848B     18.2
#>  6 fansi_vec_ansi      53µs   55.6µs    17661.    5.41KB     14.8
#>  7 cli_vec_plain     14.2µs   14.9µs    65735.      848B     19.7
#>  8 fansi_vec_plain   36.7µs   38.5µs    25424.    4.59KB     22.9
#>  9 cli_txt_ansi      19.8µs   20.6µs    47648.        0B     14.3
#> 10 fansi_txt_ansi    44.1µs   45.6µs    20702.    5.12KB     19.0
#> 11 cli_txt_plain     12.2µs   12.8µs    77181.        0B     23.2
#> 12 fansi_txt_plain   28.8µs   30.2µs    32610.      688B     29.4

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        145.62µs 150.59µs     6552.  103.31KB    21.1 
#>  2 fansi_ansi         126µs 131.16µs     7521.  102.13KB    21.1 
#>  3 base_ansi         4.11µs   4.37µs   224922.      224B    22.5 
#>  4 cli_plain       142.79µs 147.84µs     6658.    8.09KB    21.1 
#>  5 fansi_plain     123.71µs 129.26µs     7613.    9.62KB    23.3 
#>  6 base_plain         3.6µs   3.79µs   254074.        0B     0   
#>  7 cli_vec_ansi      7.16ms   7.32ms      136.  823.77KB    31.5 
#>  8 fansi_vec_ansi    1.03ms   1.07ms      911.  846.81KB    19.5 
#>  9 base_vec_ansi   154.65µs 163.56µs     6007.    22.7KB     4.11
#> 10 cli_vec_plain     7.13ms   7.35ms      136.  823.77KB    28.7 
#> 11 fansi_vec_plain 966.07µs   1.01ms      981.  845.98KB    22.1 
#> 12 base_vec_plain  108.96µs 113.38µs     8617.      848B     4.05
#> 13 cli_txt_ansi      3.24ms   3.32ms      301.    63.6KB     2.02
#> 14 fansi_txt_ansi    1.53ms   1.55ms      643.   35.05KB     2.02
#> 15 base_txt_ansi    138.4µs 147.83µs     6492.   18.47KB     2.02
#> 16 cli_txt_plain      2.4ms   2.44ms      410.    63.6KB     0   
#> 17 fansi_txt_plain 511.34µs 523.28µs     1889.    30.6KB     6.14
#> 18 base_txt_plain   91.56µs  93.69µs    10492.   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         95.18µs  99.61µs     9826.   32.23KB    19.0 
#>  2 fansi_ansi       54.24µs  57.23µs    17224.   31.43KB    14.6 
#>  3 base_ansi         1.05µs   1.09µs   858556.     4.2KB     0   
#>  4 cli_plain        93.83µs  98.22µs    10026.        0B    14.6 
#>  5 fansi_plain      53.75µs  57.09µs    17270.      872B    14.8 
#>  6 base_plain        1.01µs   1.04µs   909548.        0B     0   
#>  7 cli_vec_ansi    224.63µs 229.52µs     4309.   16.73KB     6.16
#>  8 fansi_vec_ansi  124.26µs 127.29µs     7782.    5.59KB     8.23
#>  9 base_vec_ansi    34.59µs  35.06µs    28317.      848B     0   
#> 10 cli_vec_plain   178.99µs 182.93µs     5414.   16.73KB     6.16
#> 11 fansi_vec_plain 117.86µs 121.97µs     8132.    5.59KB     8.25
#> 12 base_vec_plain   30.33µs  30.95µs    32192.      848B     0   
#> 13 cli_txt_ansi     104.8µs 108.63µs     9089.        0B    12.4 
#> 14 fansi_txt_ansi   54.04µs  57.06µs    17321.      872B    14.6 
#> 15 base_txt_ansi     1.11µs   1.16µs   819927.        0B     0   
#> 16 cli_txt_plain    95.76µs  99.44µs     9829.        0B    14.5 
#> 17 fansi_txt_plain  53.48µs  56.87µs    17365.      872B    14.7 
#> 18 base_txt_plain    1.04µs   1.08µs   880219.        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         317.6µs 326.54µs    3030.   266.59KB    12.4 
#>  2 fansi_ansi       94.96µs 101.01µs    9679.    10.29KB    12.5 
#>  3 base_ansi        38.38µs  40.64µs   24216.         0B    12.1 
#>  4 cli_plain       198.86µs 205.03µs    4746.         0B    12.4 
#>  5 fansi_plain         96µs 101.55µs    9678.       872B    14.6 
#>  6 base_plain       31.58µs  33.59µs   29048.         0B    11.6 
#>  7 cli_vec_ansi     32.39ms  32.72ms      30.5    2.48KB    20.3 
#>  8 fansi_vec_ansi  241.15µs  246.2µs    3999.     7.25KB     8.24
#>  9 base_vec_ansi     2.19ms   2.25ms     442.    48.18KB    15.1 
#> 10 cli_vec_plain    20.11ms  20.36ms      48.4    2.48KB    16.1 
#> 11 fansi_vec_plain  200.5µs 205.07µs    4793.     6.42KB     7.02
#> 12 base_vec_plain    1.56ms    1.6ms     622.     47.4KB    14.9 
#> 13 cli_txt_ansi     20.84ms  20.92ms      46.9  507.59KB     9.39
#> 14 fansi_txt_ansi  228.84µs 232.11µs    4032.     6.77KB     6.12
#> 15 base_txt_ansi     2.01ms   2.05ms     486.   582.06KB     6.34
#> 16 cli_txt_plain     1.62ms   1.67ms     597.   369.84KB     8.65
#> 17 fansi_txt_plain 181.87µs 186.75µs    5293.     2.51KB     8.24
#> 18 base_txt_plain     1.3ms   1.34ms     734.   367.31KB     6.35

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.28µs   6.87µs   142686.   23.82KB    14.3 
#>  2 fansi_ansi       77.47µs  81.87µs    12012.   28.48KB    14.7 
#>  3 base_ansi       991.04ns   1.04µs   906984.        0B     0   
#>  4 cli_plain         6.18µs   6.71µs   146045.        0B    14.6 
#>  5 fansi_plain      77.28µs  81.46µs    12085.    1.98KB    14.7 
#>  6 base_plain      971.02ns   1.01µs   942997.        0B     0   
#>  7 cli_vec_ansi     27.03µs   27.9µs    34768.     1.7KB     3.48
#>  8 fansi_vec_ansi  115.08µs 118.83µs     8268.    8.86KB    10.5 
#>  9 base_vec_ansi     5.82µs   6.14µs   161157.      848B     0   
#> 10 cli_vec_plain    22.43µs  23.54µs    41978.     1.7KB     4.20
#> 11 fansi_vec_plain 108.88µs 112.34µs     8735.    8.86KB    10.5 
#> 12 base_vec_plain     5.5µs    5.8µs   170170.      848B     0   
#> 13 cli_txt_ansi       6.2µs   6.75µs   143383.        0B    28.7 
#> 14 fansi_txt_ansi   77.52µs  81.86µs    11999.    1.98KB    12.6 
#> 15 base_txt_ansi     3.84µs    3.9µs   251364.        0B     0   
#> 16 cli_txt_plain     7.02µs   7.54µs   129484.        0B    25.9 
#> 17 fansi_txt_plain  76.98µs  81.01µs    12158.    1.98KB    12.5 
#> 18 base_txt_plain    2.65µs   2.71µs   357542.        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       105.58µs    110µs    8841.    11.88KB    10.3 
#>  2 base_ansi        1.33µs   1.38µs  702083.         0B     0   
#>  3 cli_plain       85.62µs  89.06µs   11050.     8.73KB    10.3 
#>  4 base_plain       1.02µs   1.06µs  915715.         0B     0   
#>  5 cli_vec_ansi     3.97ms   4.06ms     246.   838.77KB    18.0 
#>  6 base_vec_ansi   72.86µs  74.67µs   13313.       848B     0   
#>  7 cli_vec_plain    2.22ms   2.27ms     440.    816.9KB    17.4 
#>  8 base_vec_plain  45.37µs  45.64µs   21785.       848B     0   
#>  9 cli_txt_ansi    11.82ms   11.9ms      83.8  114.42KB     6.45
#> 10 base_txt_ansi   73.85µs  75.28µs   13215.         0B     0   
#> 11 cli_txt_plain  246.39µs 251.43µs    3937.    18.16KB     2.01
#> 12 base_txt_plain   41.9µs  43.55µs   22939.         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.2µs   78.1µs    12596.        0B    12.4 
#>  2 base_ansi        16.5µs   17.7µs    55292.        0B    11.1 
#>  3 cli_plain        73.2µs   76.8µs    12818.        0B    14.5 
#>  4 base_plain       16.6µs   17.7µs    55708.        0B    11.1 
#>  5 cli_vec_ansi    155.5µs  161.6µs     6106.     7.2KB     7.03
#>  6 base_vec_ansi    50.5µs   55.9µs    17625.    1.66KB     4.06
#>  7 cli_vec_plain   142.3µs  147.5µs     6673.     7.2KB     6.13
#>  8 base_vec_plain   46.3µs     52µs    18952.    1.66KB     6.12
#>  9 cli_txt_ansi      133µs    136µs     7193.        0B     6.09
#> 10 base_txt_ansi    35.2µs   36.3µs    27209.        0B     8.17
#> 11 cli_txt_plain   117.9µs  120.4µs     8117.        0B     8.17
#> 12 base_txt_plain   31.5µs   32.6µs    30260.        0B     6.05

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          7.97µs   8.59µs   114334.    12.3KB    22.9 
#> 2 base       891.97ns  931.9ns   998383.        0B     0   
#> 3 cli_vec     24.27µs  25.03µs    38986.      448B     3.90
#> 4 base_vec    11.33µs  11.45µs    86521.      448B     8.65
#> 5 cli_txt     24.97µs  25.64µs    38690.        0B     3.87
#> 6 base_txt    12.42µs  12.48µs    79399.        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          7.96µs   8.57µs   114855.        0B    23.0 
#> 2 base         1.27µs   1.33µs   724933.        0B     0   
#> 3 cli_vec     28.89µs  29.69µs    33399.      448B     3.34
#> 4 base_vec    45.07µs   46.7µs    21379.      448B     0   
#> 5 cli_txt     30.09µs  30.83µs    31659.        0B     6.33
#> 6 base_txt    80.73µs  82.66µs    12059.        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          8.58µs   9.26µs   106365.        0B    21.3 
#> 2 base       891.04ns 922.13ns  1032714.        0B     0   
#> 3 cli_vec     19.29µs  19.98µs    49521.      448B     4.95
#> 4 base_vec    11.33µs  11.45µs    86530.      448B     8.65
#> 5 cli_txt     20.19µs  20.83µs    47561.        0B     4.76
#> 6 base_txt    12.41µs  12.48µs    79430.        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µs   6.52µs   150614.    21.1KB    15.1 
#> 2 base         1.04µs   1.12µs   786786.        0B     0   
#> 3 cli_vec      29.5µs  30.28µs    32594.     1.7KB     6.52
#> 4 base_vec      7.7µs   7.92µs   124937.      848B     0   
#> 5 cli_txt      5.91µs   6.44µs   152246.        0B    15.2 
#> 6 base_txt     5.47µs   5.58µs   176502.        0B     0

Session info

sessioninfo::session_info()
#> ─ Session info ─────────────────────────────────────────────────────────
#>  setting  value
#>  version  R version 4.4.0 (2024-04-24)
#>  os       Ubuntu 22.04.4 LTS
#>  system   x86_64, linux-gnu
#>  ui       X11
#>  language en
#>  collate  C.UTF-8
#>  ctype    C.UTF-8
#>  tz       UTC
#>  date     2024-05-04
#>  pandoc   3.1.11 @ /opt/hostedtoolcache/pandoc/3.1.11/x64/ (via rmarkdown)
#> 
#> ─ Packages ─────────────────────────────────────────────────────────────
#>  package     * version    date (UTC) lib source
#>  bench         1.1.3      2023-05-04 [1] RSPM
#>  bslib         0.7.0      2024-03-29 [1] RSPM
#>  cachem        1.0.8      2023-05-01 [1] RSPM
#>  cli         * 3.6.2.9000 2024-05-04 [1] local
#>  codetools     0.2-20     2024-03-31 [3] CRAN (R 4.4.0)
#>  desc          1.4.3      2023-12-10 [1] RSPM
#>  digest        0.6.35     2024-03-11 [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.4      2024-04-25 [1] RSPM
#>  glue          1.7.0      2024-01-09 [1] RSPM
#>  htmltools     0.5.8.1    2024-04-04 [1] RSPM
#>  htmlwidgets   1.6.4      2023-12-06 [1] RSPM
#>  jquerylib     0.1.4      2021-04-26 [1] RSPM
#>  jsonlite      1.8.8      2023-12-04 [1] RSPM
#>  knitr         1.46       2024-04-06 [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.9      2024-04-18 [1] any (@2.0.9)
#>  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.3.0      2024-03-13 [1] RSPM
#>  rlang         1.1.3      2024-01-10 [1] RSPM
#>  rmarkdown     2.26       2024-03-05 [1] RSPM
#>  sass          0.4.9      2024-03-15 [1] RSPM
#>  sessioninfo   1.2.2      2021-12-06 [1] RSPM
#>  systemfonts   1.0.6      2024-03-07 [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.43       2024-03-25 [1] RSPM
#>  yaml          2.3.8      2023-12-11 [1] RSPM
#> 
#>  [1] /home/runner/work/_temp/Library
#>  [2] /opt/R/4.4.0/lib/R/site-library
#>  [3] /opt/R/4.4.0/lib/R/library
#> 
#> ────────────────────────────────────────────────────────────────────────