R - добавление значений в матрицу, какой цикл использовать и использовать память - PullRequest
0 голосов
/ 18 октября 2018

Я разрабатываю пакет 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.

...