ANSI function benchmarks
Gábor Csárdi
2025-02-13
Source:vignettes/ansi-benchmark.Rmd
ansi-benchmark.Rmd
$output function (x, options) { if (class == “output” && output_asis(x, options)) return(x) hook.t(x, options[[paste0(“attr.”, class)]], options[[paste0(“class.”, class)]]) } <bytecode: 0x55baa1df0c08> <environment: 0x55baa28418a0>
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.
ansi <- format_inline(
"{col_green(symbol$tick)} {.code print(x)} {.emph emphasised}"
)
plain <- ansi_strip(ansi)
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 43.9µs 47µs 20649. 99.2KB 18.9
#> 2 plain 44µs 47.2µs 20573. 0B 19.6
#> 3 base 11.1µs 12.2µs 79453. 48.4KB 15.9
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 45µs 48.2µs 19967. 0B 20.9
#> 2 plain 44.8µs 47.3µs 20393. 0B 23.3
#> 3 base 13µs 14µs 69281. 0B 20.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 105.74µs 112.07µs 8667. 75.02KB 16.7
#> 2 plain 83.8µs 88.66µs 10922. 8.73KB 14.6
#> 3 base 1.84µs 1.96µs 491077. 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 322µs 344µs 2872. 33.15KB 18.8
#> 2 plain 322µs 342µs 2891. 1.09KB 21.1
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.62µs 6.12µs 156958. 9.19KB 31.4
#> 2 fansi_ansi 29.61µs 32.08µs 30259. 4.18KB 24.2
#> 3 cli_plain 5.64µs 6.13µs 158520. 0B 31.7
#> 4 fansi_plain 29.21µs 31.5µs 30641. 688B 24.5
#> 5 cli_vec_ansi 6.98µs 7.35µs 132766. 448B 13.3
#> 6 fansi_vec_ansi 38.53µs 40.23µs 24093. 5.02KB 19.3
#> 7 cli_vec_plain 7.55µs 7.97µs 122718. 448B 24.5
#> 8 fansi_vec_plain 36.89µs 38.59µs 25263. 5.02KB 20.2
#> 9 cli_txt_ansi 5.63µs 5.93µs 163943. 0B 32.8
#> 10 fansi_txt_ansi 29.34µs 30.82µs 30388. 688B 24.3
#> 11 cli_txt_plain 6.46µs 6.79µs 143495. 0B 14.4
#> 12 fansi_txt_plain 37.02µs 38.75µs 25143. 5.02KB 20.1
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 59.8µs 61.8µs 15306. 22.6KB 8.15
#> 2 fansi 111.6µs 114.5µs 8553. 55.3KB 8.16
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.49µs 7.07µs 136627. 0B 27.3
#> 2 fansi_ansi 88.06µs 91.48µs 10607. 38.84KB 16.6
#> 3 base_ansi 911.07ns 942.15ns 1007532. 0B 101.
#> 4 cli_plain 6.49µs 6.98µs 138855. 0B 13.9
#> 5 fansi_plain 87.78µs 92.06µs 10430. 688B 16.7
#> 6 base_plain 820.96ns 942.15ns 790763. 0B 79.1
#> 7 cli_vec_ansi 29.25µs 30.14µs 32578. 448B 3.26
#> 8 fansi_vec_ansi 107.53µs 112.71µs 8630. 5.02KB 14.6
#> 9 base_vec_ansi 18.48µs 18.57µs 53139. 448B 0
#> 10 cli_vec_plain 28.05µs 28.79µs 34125. 448B 6.83
#> 11 fansi_vec_plain 99.53µs 104.39µs 9303. 5.02KB 14.7
#> 12 base_vec_plain 10.85µs 10.93µs 90202. 448B 0
#> 13 cli_txt_ansi 29.16µs 29.86µs 32913. 0B 6.58
#> 14 fansi_txt_ansi 101.2µs 106.32µs 9101. 688B 14.6
#> 15 base_txt_ansi 18.2µs 18.25µs 53783. 0B 0
#> 16 cli_txt_plain 27.37µs 28.04µs 35021. 0B 7.01
#> 17 fansi_txt_plain 90.93µs 95.74µs 10121. 688B 16.8
#> 18 base_txt_plain 10.59µs 11.09µs 84023. 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.27µs 8.92µs 108575. 0B 32.6
#> 2 fansi_ansi 88.77µs 93.09µs 10419. 688B 16.6
#> 3 base_ansi 1.22µs 1.26µs 761886. 0B 0
#> 4 cli_plain 8.19µs 8.72µs 111611. 0B 22.3
#> 5 fansi_plain 88.71µs 92.48µs 10420. 688B 16.6
#> 6 base_plain 1µs 1.05µs 909690. 0B 91.0
#> 7 cli_vec_ansi 34.1µs 35.17µs 27764. 448B 5.55
#> 8 fansi_vec_ansi 117.23µs 120.89µs 8042. 5.02KB 12.4
#> 9 base_vec_ansi 42.99µs 44.15µs 22448. 448B 0
#> 10 cli_vec_plain 33.3µs 33.97µs 28934. 448B 5.79
#> 11 fansi_vec_plain 107.35µs 111.44µs 8680. 5.02KB 14.5
#> 12 base_vec_plain 22.96µs 23.3µs 42425. 448B 0
#> 13 cli_txt_ansi 34.73µs 35.6µs 27637. 0B 8.29
#> 14 fansi_txt_ansi 107.25µs 111.72µs 8731. 688B 12.4
#> 15 base_txt_ansi 45.55µs 46.73µs 21163. 0B 2.12
#> 16 cli_txt_plain 32.64µs 33.32µs 29144. 0B 5.83
#> 17 fansi_txt_plain 98.67µs 103.75µs 8587. 688B 12.4
#> 18 base_txt_plain 24.78µs 25.3µs 39016. 0B 3.90
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.38µs 6.97µs 139387. 0B 27.9
#> 2 cli_plain 6.04µs 6.48µs 150344. 0B 15.0
#> 3 cli_vec_ansi 31.48µs 32.65µs 28910. 848B 5.78
#> 4 cli_vec_plain 10.01µs 10.62µs 92084. 848B 9.21
#> 5 cli_txt_ansi 30.67µs 31.46µs 31367. 0B 6.27
#> 6 cli_txt_plain 6.84µs 7.37µs 128483. 0B 25.7
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.2µs 80004. 0B 24.0
#> 2 fansi_ansi 27.3µs 28.7µs 33956. 7.24KB 27.2
#> 3 cli_plain 11.4µs 12.1µs 80587. 0B 24.2
#> 4 fansi_plain 26.9µs 28.5µs 34061. 688B 27.3
#> 5 cli_vec_ansi 20.5µs 21.3µs 45811. 848B 13.7
#> 6 fansi_vec_ansi 52.3µs 54.3µs 18012. 5.41KB 12.5
#> 7 cli_vec_plain 14.1µs 14.8µs 65913. 848B 26.4
#> 8 fansi_vec_plain 35.6µs 37.5µs 25994. 4.59KB 18.2
#> 9 cli_txt_ansi 20.1µs 20.8µs 47118. 0B 14.1
#> 10 fansi_txt_ansi 43.5µs 45.2µs 21613. 5.12KB 17.3
#> 11 cli_txt_plain 12.4µs 13.1µs 73893. 0B 22.2
#> 12 fansi_txt_plain 28.5µs 30.4µs 31736. 688B 25.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 142.8µs 149.42µs 6524. 104.31KB 18.9
#> 2 fansi_ansi 123.99µs 129.67µs 7518. 106.35KB 19.2
#> 3 base_ansi 3.98µs 4.28µs 229047. 224B 22.9
#> 4 cli_plain 141.37µs 148.54µs 6408. 8.09KB 16.7
#> 5 fansi_plain 124.32µs 129.97µs 7465. 9.62KB 21.3
#> 6 base_plain 3.61µs 3.81µs 257024. 0B 0
#> 7 cli_vec_ansi 7.26ms 7.37ms 135. 823.77KB 27.5
#> 8 fansi_vec_ansi 1.04ms 1.07ms 895. 846.81KB 17.2
#> 9 base_vec_ansi 153.95µs 160.47µs 6104. 22.7KB 2.03
#> 10 cli_vec_plain 7.23ms 7.38ms 134. 823.77KB 28.9
#> 11 fansi_vec_plain 968.31µs 1ms 988. 845.98KB 19.5
#> 12 base_vec_plain 107.13µs 110.19µs 8901. 848B 2.01
#> 13 cli_txt_ansi 3.35ms 3.38ms 295. 63.6KB 2.02
#> 14 fansi_txt_ansi 1.54ms 1.57ms 627. 35.05KB 2.02
#> 15 base_txt_ansi 134.89µs 143.7µs 6910. 18.47KB 2.02
#> 16 cli_txt_plain 2.47ms 2.5ms 397. 63.6KB 0
#> 17 fansi_txt_plain 518.38µs 536.93µs 1851. 30.6KB 6.15
#> 18 base_txt_plain 86.63µs 88.93µs 10903. 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.96µs 101.62µs 9258. 33.81KB 21.2
#> 2 fansi_ansi 53.25µs 56.91µs 16877. 31.43KB 21.3
#> 3 base_ansi 1.06µs 1.15µs 793788. 4.2KB 79.4
#> 4 cli_plain 95.13µs 100.57µs 9553. 0B 21.2
#> 5 fansi_plain 52.43µs 56.58µs 16873. 872B 21.5
#> 6 base_plain 1µs 1.1µs 871448. 0B 0
#> 7 cli_vec_ansi 222.09µs 230.13µs 4250. 16.73KB 10.4
#> 8 fansi_vec_ansi 120.29µs 125.91µs 7508. 5.59KB 10.4
#> 9 base_vec_ansi 44.69µs 48.1µs 20567. 848B 0
#> 10 cli_vec_plain 176.56µs 183.42µs 5240. 16.73KB 12.0
#> 11 fansi_vec_plain 116.62µs 119.81µs 8145. 5.59KB 12.5
#> 12 base_vec_plain 38.87µs 43.77µs 22632. 848B 0
#> 13 cli_txt_ansi 103.45µs 107.25µs 9017. 0B 21.1
#> 14 fansi_txt_ansi 52.13µs 55.33µs 17378. 872B 21.2
#> 15 base_txt_ansi 1.1µs 1.18µs 810735. 0B 81.1
#> 16 cli_txt_plain 93.35µs 99.11µs 9825. 0B 21.1
#> 17 fansi_txt_plain 52.44µs 55.72µs 17410. 872B 23.5
#> 18 base_txt_plain 1.02µs 1.12µs 855682. 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.52µs 335.31µs 2937. 0B 19.1
#> 2 fansi_ansi 94.9µs 100.69µs 9576. 97.33KB 21.1
#> 3 base_ansi 37.4µs 39.29µs 24472. 0B 19.6
#> 4 cli_plain 195.27µs 206.95µs 4649. 0B 18.8
#> 5 fansi_plain 93.33µs 99.14µs 9802. 872B 21.0
#> 6 base_plain 30.25µs 32.06µs 29971. 0B 21.0
#> 7 cli_vec_ansi 33.98ms 34.29ms 29.2 2.48KB 52.5
#> 8 fansi_vec_ansi 237.92µs 246.55µs 3987. 7.25KB 10.3
#> 9 base_vec_ansi 2.18ms 2.24ms 441. 48.18KB 25.8
#> 10 cli_vec_plain 20.33ms 20.45ms 48.7 2.48KB 29.2
#> 11 fansi_vec_plain 197.84µs 205.13µs 4778. 6.42KB 12.5
#> 12 base_vec_plain 1.61ms 1.66ms 597. 47.4KB 22.0
#> 13 cli_txt_ansi 26.44ms 26.74ms 37.4 507.59KB 14.4
#> 14 fansi_txt_ansi 228.19µs 236.51µs 4164. 6.77KB 8.21
#> 15 base_txt_ansi 1.24ms 1.29ms 763. 582.06KB 20.7
#> 16 cli_txt_plain 1.22ms 1.26ms 783. 369.84KB 15.4
#> 17 fansi_txt_plain 180.29µs 187.12µs 5194. 2.51KB 10.3
#> 18 base_txt_plain 870.46µs 905.43µs 1086. 367.31KB 18.1
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.56µs 7.1µs 136059. 24.81KB 27.2
#> 2 fansi_ansi 77.26µs 82.52µs 11561. 28.48KB 21.4
#> 3 base_ansi 982.08ns 1.03µs 916176. 0B 0
#> 4 cli_plain 6.52µs 7.14µs 136280. 0B 27.3
#> 5 fansi_plain 77.89µs 81.97µs 11828. 1.98KB 21.3
#> 6 base_plain 952.04ns 1µs 933592. 0B 0
#> 7 cli_vec_ansi 27.14µs 28.5µs 34441. 1.7KB 6.89
#> 8 fansi_vec_ansi 112.86µs 118.2µs 8247. 8.86KB 14.9
#> 9 base_vec_ansi 6.2µs 6.4µs 151953. 848B 15.2
#> 10 cli_vec_plain 22.81µs 23.89µs 41093. 1.7KB 8.22
#> 11 fansi_vec_plain 106.89µs 113.22µs 8615. 8.86KB 14.9
#> 12 base_vec_plain 5.99µs 6.07µs 161311. 848B 0
#> 13 cli_txt_ansi 6.57µs 7.17µs 135125. 0B 40.5
#> 14 fansi_txt_ansi 77.69µs 82.14µs 11840. 1.98KB 19.1
#> 15 base_txt_ansi 6.39µs 6.46µs 151843. 0B 15.2
#> 16 cli_txt_plain 7.31µs 7.78µs 125755. 0B 25.2
#> 17 fansi_txt_plain 76.13µs 79.85µs 12144. 1.98KB 21.3
#> 18 base_txt_plain 4.06µs 4.11µs 237452. 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 100.01µs 104.77µs 9252. 11.85KB 16.8
#> 2 base_ansi 1.33µs 1.39µs 697864. 0B 0
#> 3 cli_plain 80.82µs 84.97µs 11330. 8.73KB 14.6
#> 4 base_plain 1.01µs 1.05µs 908132. 0B 0
#> 5 cli_vec_ansi 3.95ms 4.03ms 248. 838.77KB 31.6
#> 6 base_vec_ansi 79.27µs 79.64µs 12142. 848B 0
#> 7 cli_vec_plain 2.23ms 2.31ms 427. 816.9KB 27.7
#> 8 base_vec_plain 46.39µs 47.2µs 20919. 848B 0
#> 9 cli_txt_ansi 14.66ms 14.79ms 67.5 114.42KB 6.53
#> 10 base_txt_ansi 78.98µs 80.36µs 12326. 0B 0
#> 11 cli_txt_plain 264.3µs 271.77µs 3614. 18.16KB 4.05
#> 12 base_txt_plain 43.99µs 45.66µs 21736. 0B 2.17
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 71.9µs 75.7µs 12802. 0B 21.1
#> 2 base_ansi 16µs 17µs 57024. 0B 22.8
#> 3 cli_plain 71.6µs 75.4µs 12775. 0B 21.1
#> 4 base_plain 15.9µs 16.9µs 57631. 0B 17.3
#> 5 cli_vec_ansi 170.8µs 177.3µs 5514. 7.2KB 10.3
#> 6 base_vec_ansi 56.2µs 61.2µs 15943. 1.66KB 6.11
#> 7 cli_vec_plain 157.2µs 163.2µs 5994. 7.2KB 8.21
#> 8 base_vec_plain 50.3µs 55.4µs 17693. 1.66KB 8.19
#> 9 cli_txt_ansi 147.6µs 152.3µs 6430. 0B 10.3
#> 10 base_txt_ansi 40.2µs 41.4µs 23684. 0B 9.48
#> 11 cli_txt_plain 131.2µs 135.7µs 7218. 0B 10.2
#> 12 base_txt_plain 34.7µs 35.7µs 27403. 0B 11.0
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.95µs 8.55µs 113462. 0B 34.0
#> 2 base 852.04ns 902.1ns 818099. 0B 0
#> 3 cli_vec 23.59µs 24.21µs 40491. 448B 8.10
#> 4 base_vec 11.53µs 11.71µs 84360. 448B 0
#> 5 cli_txt 23.63µs 24.11µs 40774. 0B 8.16
#> 6 base_txt 12.49µs 12.56µs 78578. 0B 7.86
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.89µs 8.36µs 116963. 0B 23.4
#> 2 base 1.27µs 1.34µs 722050. 0B 0
#> 3 cli_vec 28.73µs 29.64µs 33076. 448B 9.93
#> 4 base_vec 50.95µs 51.44µs 19241. 448B 0
#> 5 cli_txt 29.32µs 29.96µs 32849. 0B 6.57
#> 6 base_txt 86.64µs 87.22µs 11348. 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.27µs 8.77µs 111549. 0B 22.3
#> 2 base 851.11ns 902.1ns 1054218. 0B 0
#> 3 cli_vec 19.34µs 19.92µs 49303. 448B 14.8
#> 4 base_vec 11.51µs 11.7µs 83927. 448B 0
#> 5 cli_txt 19.93µs 20.59µs 46363. 0B 9.27
#> 6 base_txt 12.49µs 12.57µs 78064. 0B 7.81
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.11µs 6.48µs 150343. 22.1KB 30.1
#> 2 base 991.04ns 1.04µs 913225. 0B 0
#> 3 cli_vec 29.06µs 29.91µs 32897. 1.7KB 9.87
#> 4 base_vec 7.79µs 7.97µs 123124. 848B 0
#> 5 cli_txt 6.09µs 6.54µs 147923. 0B 29.6
#> 6 base_txt 5.39µs 5.45µs 178993. 0B 17.9
Session info
sessioninfo::session_info()
#> ─ Session info ──────────────────────────────────────────────────────
#> setting value
#> version R version 4.4.2 (2024-10-31)
#> os Ubuntu 24.04.1 LTS
#> system x86_64, linux-gnu
#> ui X11
#> language en
#> collate C.UTF-8
#> ctype C.UTF-8
#> tz UTC
#> date 2025-02-13
#> pandoc 3.1.11 @ /opt/hostedtoolcache/pandoc/3.1.11/x64/ (via rmarkdown)
#> quarto NA
#>
#> ─ Packages ──────────────────────────────────────────────────────────
#> package * version date (UTC) lib source
#> bench 1.1.4 2025-01-16 [1] RSPM
#> bslib 0.9.0 2025-01-30 [1] RSPM
#> cachem 1.1.0 2024-05-16 [1] RSPM
#> cli * 3.6.4 2025-02-13 [1] local
#> codetools 0.2-20 2024-03-31 [3] CRAN (R 4.4.2)
#> desc 1.4.3 2023-12-10 [1] RSPM
#> digest 0.6.37 2024-08-19 [1] RSPM
#> evaluate 1.0.3 2025-01-10 [1] RSPM
#> fansi * 1.0.6 2023-12-08 [1] RSPM
#> fastmap 1.2.0 2024-05-15 [1] RSPM
#> fs 1.6.5 2024-10-30 [1] RSPM
#> glue 1.8.0 2024-09-30 [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.9 2024-09-20 [1] RSPM
#> knitr 1.49 2024-11-08 [1] RSPM
#> lifecycle 1.0.4 2023-11-07 [1] RSPM
#> magrittr 2.0.3 2022-03-30 [1] RSPM
#> pillar 1.10.1 2025-01-07 [1] RSPM
#> pkgconfig 2.0.3 2019-09-22 [1] RSPM
#> pkgdown 2.1.1 2024-09-17 [1] any (@2.1.1)
#> profmem 0.6.0 2020-12-13 [1] RSPM
#> R6 2.6.0 2025-02-12 [1] RSPM
#> ragg 1.3.3 2024-09-11 [1] RSPM
#> rlang 1.1.5 2025-01-17 [1] RSPM
#> rmarkdown 2.29 2024-11-04 [1] RSPM
#> sass 0.4.9 2024-03-15 [1] RSPM
#> sessioninfo 1.2.3 2025-02-05 [1] any (@1.2.3)
#> systemfonts 1.2.1 2025-01-20 [1] RSPM
#> textshaping 1.0.0 2025-01-20 [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.50 2025-01-07 [1] RSPM
#> yaml 2.3.10 2024-07-26 [1] RSPM
#>
#> [1] /home/runner/work/_temp/Library
#> [2] /opt/R/4.4.2/lib/R/site-library
#> [3] /opt/R/4.4.2/lib/R/library
#> * ── Packages attached to the search path.
#>
#> ─────────────────────────────────────────────────────────────────────