Вы можете сократить время, минимизировав количество циклов, и в дальнейшем сделайте это, используя пакет parallel
... Мой подход заключается в разбиении строк один раз, затем в цикле сортировка и вставка:
sort_cat <- function(strings){
tmp <- strsplit(strings, split="")
tmp <- lapply(tmp, sort)
tmp <- lapply(tmp, paste0, collapse = "")
tmp <- unlist(tmp)
return(tmp)
}
sort_cat2 <- function(strings){
unlist(mcMap(function(i){
stri_join(sort(i), collapse = "")
}, stri_split_regex(strings, "|", omit_empty = TRUE, simplify = F), mc.cores = 8L))
}
> microbenchmark::microbenchmark(
+ old = sort_cat(strings[1:500000]),
+ new = sort_cat2(strings[1:500000]),
+ times = 1
+ )
Unit: seconds
expr min lq mean median uq max neval
old 9.62673395 9.62673395 9.62673395 9.62673395 9.62673395 9.62673395 1
new 5.10547437 5.10547437 5.10547437 5.10547437 5.10547437 5.10547437 1
Бреется, как 4 секунды, но все еще не так быстро ...
Редактировать
Хорошо, теперь все в порядке, используя стратегию apply
..:
1) извлекать буквы, а не разбивать границы 2) создавать матрицу с результатами 3) перебирать по строкам 4) сортировать 5) объединять
Вы избегаете многократных циклов и списков ... IGNORE: ? Предостережение: если строки различной длины, вам необходимо удалить все пустые или NA в пределах apply
, такие как i[!is.na(i) && nchar(i) > 0]
sort_cat3 <- function(strings){
apply(stri_extract_all_regex(strings, "\\p{L}", simplify = TRUE), 1, function(i){
stri_join(stri_sort(i), collapse = "")
})
}
> microbenchmark::microbenchmark(
+ old = sort_cat(strings[1:500000]),
+ mapping = sort_cat2(strings[1:500000]),
+ applying = sort_cat3(strings[1:500000]),
+ times = 1
+ )
Unit: seconds
expr min lq mean median uq max neval
old 10.35101934 10.35101934 10.35101934 10.35101934 10.35101934 10.35101934 1
mapping 5.12771799 5.12771799 5.12771799 5.12771799 5.12771799 5.12771799 1
applying 3.97775326 3.97775326 3.97775326 3.97775326 3.97775326 3.97775326 1
Занимает у нас от 10,3 с до 3,98