转换为整数然后使用 %% 和 %/% 计算数字对于 25,000,000 长度的向量似乎是最快的:
a <- as.character(sample(1:1e6, size = 25e6, replace = TRUE))
use_grepl <- function(x) {
o <- integer(length(x))
o[grep('1', x, fixed = TRUE)] <- 1L
o[grep('2', x, fixed = TRUE)] <- 2L
o[grep('3', x, fixed = TRUE)] <- 3L
o[grep('4', x, fixed = TRUE)] <- 4L
o[grep('5', x, fixed = TRUE)] <- 5L
o[grep('6', x, fixed = TRUE)] <- 6L
o[grep('7', x, fixed = TRUE)] <- 7L
o[grep('8', x, fixed = TRUE)] <- 8L
o[grep('9', x, fixed = TRUE)] <- 9L
o
}
use_strsplit <- function(x) {
tbl19 <- as.character(1:9)
vapply(strsplit(x, split = "", fixed = TRUE),
function(v) {
max(fmatch(v, table = tbl19, nomatch = 0L))
},
0L)
}
use_mod <- function(xx) {
nth_digit_of <- function (x, n) {
{x %% 10^n} %/% 10^{n - 1L}
}
v <- as.integer(xx)
most_digits <- as.integer(ceiling(log10(max(v))) + 1)
o <- nth_digit_of(v, 1L)
for (vj in 2:most_digits) {
o <- pmax.int(o, nth_digit_of(v, vj))
}
as.integer(o)
}
doit4 <- function(V) as.numeric(sapply(strsplit(V, ""), max))
bench::mark(use_mod(a), use_grepl(a), doit4(a))
# A tibble: 3 x 14
expression min mean median max `itr/sec` mem_alloc n_gc n_itr total_time result memory time
<chr> <bch> <bch> <bch:> <bch> <dbl> <bch:byt> <dbl> <int> <bch:tm> <list> <list> <lis>
1 use_mod(a) 14.4s 14.4s 14.4s 14.4s 0.0693 2.61GB 3 1 14.4s <int ~ <Rpro~ <bch~
2 use_grepl~ 38.2s 38.2s 38.2s 38.2s 0.0262 1.32GB 0 1 38.2s <int ~ <Rpro~ <bch~
3 doit4(a) 56.5s 56.5s 56.5s 56.5s 0.0177 1.18GB 7 1 56.5s <dbl ~ <Rpro~ <bch~