Я разрабатываю пакет R и для некоторых процессов внутри него мне нужно вычислить кучу больших матриц.Однако было использовано много оперативной памяти, поэтому я попытался провести некоторое исследование.
(я попытался следовать общеизвестному совету избегать циклов, где это возможно, и использовать вместо него семейство apply)
Вот мой минимальный пример;
library(pryr)
test1 <- function(nbyn) {
values <- matrix(nrow=nbyn, ncol=nbyn)
rownames(values) <- 1:nrow(values)
values[,] <- 2
lapply(rownames(values) , function(row) {
values[row,] <<- rnorm(1)*values[row,]
})
gc()
1
}
test2 <- function(nbyn) {
values <- matrix(nrow=nbyn, ncol=nbyn)
rownames(values) <- 1:nrow(values)
values[,] <- 2
for (row in rownames(values)) {
values[row,] <- rnorm(1)*values[row,]
}
gc()
1
}
# comment at for loops indicate before/after ram that's being used in system. (manually measured)
# apply seems to have more memory leaks/left over garbage?
# run both blocks seperately in new r sessions (to clear memory)
# add startmem and stopmem into global environment as to not disturb measurement
startmem <- mem_used()
stopmem <- mem_used()
# start actual test
start <- Sys.time()
startmem <- mem_used()
for (i in 1:10) {
test1(10000) # 2.06 -> 4.21 gb (3.50 gb after garbage collection) ---> at least 1.44gb gets left in ram?
}
gc()
stopmem <- mem_used()
print(paste0("process left ", stopmem-startmem, " bytes of ram"))
print(Sys.time()-start)
#---
# add startmem and stopmem into global environment as to not disturb measurement
startmem <- mem_used()
stopmem <- mem_used()
# start actual test
start <- Sys.time()
startmem <- mem_used()
for (i in 1:10) {
test2(10000) # 2.06 -> 3.87 gb (3.12 gb after garbage collection) ---> at least 1.06gb gets left in ram?
}
gc()
stopmem <- mem_used()
print(paste0("process left ", stopmem-startmem, " bytes of ram"))
print(Sys.time()-start)
Кажется, что apply применяет / оставляет больше памяти, о которой не заботится сборщик мусора.Я думаю, что это связано с попытками объединить результаты, но я не уверен.Например, может ли это быть связано с присваиванием <<-
?Применяется ли вообще говоря больше памяти, чем обычные для циклов?Кажется проблематичным, что я не хочу сохранять применяемые значения, но не могу их игнорировать.
Я знаю, что это некрасиво использовать назначение <<-
, но это единственный способ поместить что-то ввнешняя ссылка от приложения, и мне нужно использовать имена для индексации, что затрудняет это.
Этот конкретный пример работает с именами матрицы вместо индексов, потому что мой пакет работает так же для удобства чтения / простоты реализации.
И последний вопрос;почему R сообщает, что у него так мало используемой памяти, а в действительности он оставляет много неиспользуемых данных в памяти, вызывая проблемы? ...
Заранее благодарен за любые ответы!
Edit1;В этом случае я буду использовать регулярные циклы for.