Как сказал Чейз: используйте силу векторизации.Здесь вы сравниваете два плохих решения.
Чтобы выяснить, почему ваше решение для применения медленнее:
В цикле for вы фактически используете векторизованные индексы матрицы, что означает отсутствие преобразованиятипа происходит.Здесь я немного грубоват, но в основном внутренний расчет игнорирует размеры.Они просто сохраняются как атрибут и возвращаются с вектором, представляющим матрицу.Чтобы проиллюстрировать:
> x <- 1:10
> attr(x,"dim") <- c(5,2)
> y <- matrix(1:10,ncol=2)
> all.equal(x,y)
[1] TRUE
Теперь, когда вы используете команду apply, матрица разбивается внутри на 100 000 векторов строк, каждый вектор строк (т.е. одно число) пропускается через функцию, и в концерезультат объединяется в соответствующую форму.Функция apply считает вектор наилучшим в этом случае и, следовательно, должен объединить результаты всех строк.Это требует времени.
Также функция sapply сначала использует as.vector(unlist(...))
, чтобы преобразовать что-либо в вектор, и в конце пытается упростить ответ в подходящую форму.Кроме того, это требует времени, следовательно, также саппли может быть медленнее.Тем не менее, это не на моей машине.
ЕСЛИ бы применить решение здесь (и это не так), вы можете сравнить:
> system.time(loop_million <- mash(million))
user system elapsed
0.75 0.00 0.75
> system.time(sapply_million <- matrix(unlist(sapply(million,squish,simplify=F))))
user system elapsed
0.25 0.00 0.25
> system.time(sapply2_million <- matrix(sapply(million,squish)))
user system elapsed
0.34 0.00 0.34
> all.equal(loop_million,sapply_million)
[1] TRUE
> all.equal(loop_million,sapply2_million)
[1] TRUE