Вы уже получили ответ о том, как использовать более одного ядра, но реальная проблема заключается в том, как вы пишете свои циклы. Никогда не расширяйте ваш результирующий вектор / объект на каждой итерации цикла . Если вы сделаете это, вы заставите R скопировать ваш вектор / объект результата и расширить его, что занимает много времени. Вместо этого предварительно выделите достаточно места для хранения, прежде чем начинать цикл, и заполните его по мере продвижения. Вот пример:
set.seed(1)
p1 <- matrix(rnorm(10000), ncol=100)
system.time({
p1max <- p1mean <- p1sum <- numeric(length = 100)
for(i in seq_along(p1max)){
p1max[i] <- max(p1[i,])
p1mean[i] <- mean(p1[i,])
p1sum[i ]<- sum(p1[i,])
}
})
user system elapsed
0.005 0.000 0.005
Или вы можете сделать это через apply()
:
system.time({
p1max2 <- apply(p1, 1, max)
p1mean2 <- apply(p1, 1, mean)
p1sum2 <- apply(p1, 1, sum)
})
user system elapsed
0.007 0.000 0.006
Но обратите внимание, что это не быстрее, чем делать цикл правильно, а иногда и медленнее.
Однако всегда следите за векторизованным кодом. Вы можете использовать суммы строк и средства, используя rowSums()
и rowMeans()
которые быстрее, чем цикл или apply
версии:
system.time({
p1max3 <- apply(p1, 1, max)
p1mean3 <- rowMeans(p1)
p1sum3 <- rowSums(p1)
})
user system elapsed
0.001 0.000 0.002
Если бы я был игроком на ставки, у меня были бы деньги на третий подход, который я упомянул об избиении, foreach()
или другие многоядерные опции в тесте скорости на вашей матрице, потому что они должны были бы значительно ускорить процесс, чтобы оправдать накладные расходы, возникающие при настройке отдельные процессы, которые обрабатываются различными ядрами процессора.
Обновление: после комментария от @shabbychef, быстрее ли сделать суммы один раз и повторно использовать в вычислении среднего?
system.time({
p1max4 <- apply(p1, 1, max)
p1sum4 <- rowSums(p1)
p1mean4 <- p1sum4 / ncol(p1)
})
user system elapsed
0.002 0.000 0.002
Не в этом тесте, но это далеко не исчерпывающий ...