Zachary
Zachary

Reputation: 381

Memory (de)allocation in R loops (without dataframes or growing objects)

Consider a simple function that takes a set of probabilities p and computes p*(1-p), assiging it to pq.

If I call it once, profiling the time & memory allocation

p <- runif(1e8)
profvis::profvis({for(i in 1:1) {pq <- p*(1-p)}})

enter image description here I see that it takes some time and memory, and requires some garbage collection. Ok, fine.

But, if I call it twice

profvis::profvis({for(i in 1:2) {pq <- p*(1-p)}})

enter image description here it requires about twice as much memory and time, and the <GC> starts to dominate the time. I think this is happening because memory is allocated to pq in the first iteration, de-allocated at the end of the iteration, then re-allocated in the second iteration. In my application this is a problem because I need to call this kind of function repeatedly (obviously with a different p each time).

I may be thinking about memory (de)allocation in the wrong way. But, is it possible to simply reuse the memory occupied by pq, rather than de-allocate then re-allocate the necessary memory in each iteration?

Upvotes: 2

Views: 136

Answers (1)

Rui Barradas
Rui Barradas

Reputation: 76402

Allocate pq beforehand and in the loop use pq[] instead. It will reassign in place and GC is avoided.

p <- runif(1e8)
pq <- numeric(length(p))
profvis::profvis({for(i in 1:2) {pq[] <- p*(1-p)}})

enter image description here


Note

The profvis output of the first code, looping just once is

p <- runif(1e8)
profvis::profvis({for(i in 1:1) {pq <- p*(1-p)}})

enter image description here

Upvotes: 1

Related Questions