[R] filling a list faster
Prof Brian Ripley
ripley at stats.ox.ac.uk
Fri Jul 13 13:55:45 CEST 2007
On Fri, 13 Jul 2007, Philippe Grosjean wrote:
> If all the data coming from your iterations are numeric (as in your toy
> example), why not to use a matrix with one row per iteration? Also, do
> preallocate the matrix and do not add row or column names before the end
> of the calculation. Something like:
>
> > m <- matrix(rep(NA, 3*10^5), ncol = 3)
> > system.time(for(i in (1:10^5)) m[i, ] <- c(i,i+1,i))
> user system elapsed
> 1.362 0.033 1.424
>
> That is, about 1.5sec on my Intel Duo Core 2.33Mhz MacBook Pro, compared to:
>
> > l <- list("1"<-c(1,2,3))
> > system.time(for(i in (1:10^5)) l[[length(l)+1]] <- c(i,i+1,i))
> user system elapsed
> 191.629 49.110 248.454
>
> ... more than 4 minutes for your code.
>
> By the way, what is your "very fast machine", that is actually four
> times faster than mine (grrrrr!)?
He said 'over a minute', not how long exactly.
But it is not just the machine but also the OS: memory management on MacOS
(it you are running MacOS) is known to be slow under some circumstances.
It took about 100s under 64-bit Linux on my 2.4Ghz Intel Core 2 Duo.
Preallocating the list helps here
l <- vector("list", 10^5)
system.time(for(i in (1:10^5)) l[[i]] <- c(i,i+1,i))
takes well under a second.
If you don't know the length and know an upper bound, just use that.
The storage allocated is only one pointer per element. And if you don't
even know an upper bound, start with a reasonable number and use
length(l) <- 1.5*length(l)
when you need to.
There are some ideas for doing this internally (R vectors have a LENGTH
and TRUELENGTH field and so could over-allocate). The problem is that
they would penalize careful coding to ameliorate the effects of careless
coding. (One of the most basic points in S/R programming is that you
avoid growing vectors.)
--
Brian D. Ripley, ripley at stats.ox.ac.uk
Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/
University of Oxford, Tel: +44 1865 272861 (self)
1 South Parks Road, +44 1865 272866 (PA)
Oxford OX1 3TG, UK Fax: +44 1865 272595
More information about the R-help
mailing list