Anyone have a clue why assigning to a list field in a RefClass is so much 
slower than assigning to a plain old list?
For example, given a list of length N, if I want to assign a value to each 
entry, then the running time is quadratic in N.
That is, refclass$a.list[[i]] <- value is much much slower than a.list[[i]] <- 
value.

Here are numbers of inserts per second for different sized lists.  "Ordinary" 
refers to just assigning to a list.  "Outside" and "Inside" refer to modifying 
a list field directly or via a method.  (The increasing rate for "ordinary" is 
just because it's so fast and there's poor precision for small Ns.)

INSERTS PER SECOND
      Outside    Inside Ordinary
100  5000.000 25000.000 100000.0
200  5405.405 18181.818 200000.0
400  4040.404 14814.815 200000.0
800  3041.825  9876.543 400000.0
1600 2133.333  7339.450 533333.3
3200 1753.425  4377.565 533333.3

You can see that the rate for inserts decreases dramatically as the size of the 
list increases.

Quadratic running time might happen for i=1:N if there was a copy operation up 
to i each time.  But why is this happening for refClasses?  And is there any 
workaround?

Pardon my quick hacky R, but here's what generated the timings above:

tg <- 
  setRefClass('tg', 
              fields = list(tags = "list",n="integer"),
              methods=list(
                initialize=function(n) {
                  n <<- n
                  reset()
                },
                reset=function() {
                  tags <<- list()
                  tags[1:n] <<- list(rep(list(),n))
                },
                set=function() {
                  reset()
                  for (i in 1:length(tags)) { tags[[i]] <<- 'foo'}
                }
              )
  )

Ns <- c(100L,200L,400L,800L,1600L,3200L)
z<-
lapply(Ns, function(n) {
  t <- tg$new(n)
  c(system.time(for (i in 1:n) {  t$tags[[i]] <- 'foo' })[3],
    system.time(t$set())[3],
    system.time({tags <- list(); tags[1:n] <- list(rep(list(),n)); for (i in 
1:n) {  tags[[i]] <- 'foo' }})[3]
  )
})
df <- as.data.frame(t(as.data.frame(z))); 
rownames(df) <- Ns
colnames(df) <- c('Outside','Inside','Ordinary')

print(Ns/df)

df$x <- Ns
qplot(x,Outside,df)
        [[alternative HTML version deleted]]

______________________________________________
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

Reply via email to