2

When playing with large objects the memory and speed implications of pass-by-value can be substantial.

R has several ways to pass-by-reference:

  • Reference Classes
  • R.oo
  • C/C++/other external languages
  • Environments

However, many of them require considerable overhead (in terms of code complexity and programmer time).

In particular, I'm envisioning something like what you could use constant references for in C++ : pass a large object, compute on it without modifying that, and return the results of that computation.

Since R does not have a concept of constants, I suspect if this happens anywhere, it's in compiled R functions, where the compiler could see that the formal argument was not modified anywhere in the code and pass it by reference.

Does the R compiler pass-by-reference if an argument is not modified? If not, are there any technical barriers to it doing so or has it just not been implemented yet?


Example code:

n <- 10^7
bigdf <- data.frame( x=runif(n), y=rnorm(n), z=rt(n,5) )
myfunc <- function(dat) invisible(with( dat, x^2+mean(y)+sqrt(exp(z)) ))
library(compiler)
mycomp <- compile(myfunc)
tracemem(bigdf)
> myfunc(bigdf)
> # No object was copied!  Question is not necessary
Community
  • 1
  • 1
Ari B. Friedman
  • 71,271
  • 35
  • 175
  • 235
  • Methinks the answer is in [the previous question](http://stackoverflow.com/questions/2603184/r-pass-by-reference): environments. If that does not answer your question, could you reword / refocus the question to make clear what besides Reference Classes and other OO approaches --- and environments --- you consider permissible? – Dirk Eddelbuettel Aug 01 '12 at 03:05
  • In writing out a clearer example, I realized that R already does optimization in that it doesn't copy objects that aren't modified. Voting to close/delete. I knew that it just didn't occur to me that it was the same phenomenon. Egg, meet face. – Ari B. Friedman Aug 01 '12 at 11:18
  • I think we should leave it open to provide another target for the next person wondering about this as you enhanced the question well. – Dirk Eddelbuettel Aug 01 '12 at 11:33
  • I migrated my aha moment over to the other question as an answer, so perhaps close as duplicate? – Ari B. Friedman Aug 01 '12 at 11:34

1 Answers1

1

This may be way off base for what you need, but what about wrapping the object in a closure? This function makes a function that knows about the object given to its parent, here I use the tiny volcano to do a very simple job.

mkFun <- function(x) {
    function(rownumbers) {
    rowSums(x[rownumbers , , drop = FALSE])
    }
}


fun <- mkFun(volcano)

fun(2)  ##1] 6493
fun(2:3)  ##[1] 6493 6626

Now fun can get passed around by worker functions to do its job as it likes.

mdsumner
  • 29,099
  • 6
  • 83
  • 91