On 01/02/2010 05:56 PM, Duncan Murdoch wrote:

On 02/01/2010 11:36 AM, Laurent Gautier wrote:
[Disclaimer: what is below reflects my understanding from reading the
R source, others will correct where deemed necessary]

On 1/2/10 12:00 PM, r-devel-requ...@r-project.org wrote:
Hello,

We are currently making lots of changes to Rcpp (see the open Rcpp
mailing list if interested [1] in the details).

We are now using [2] R_PreserveObject and R_ReleaseObject to manage
garbage collection instead of the PROTECT/UNPROTECT dance. This seems to
work well, but I was wondering if there was documentation about it.

The most precise technical documentation is in memory.c
PROTECT is an alias for Rf_protect, itself an alias for
SEXP protect(SEXP s);
and uses a stack (R_PPStack) to store protected objects.

In particular, if we preserve the same SEXP twice (or more), should we
implement some sort of reference counting ?

This depends on the requirements for your system.

For example, in rpy2 I added a reference counting layer(*) because I
wanted to allow several Python objects to share the same underlying R
object, but that's not currently(*) counting how many times an object
should be freed.
(*: imperfect, but currently doing a very decent job - details upon
request).

That kind of feature could be provided by R's C-level API, since this
could be seen of general use as well as give an opportunity to improve
the performances of the R_PreservedObject/R_ReleaseObject duo whenever
a lot of objects are protected and/or external code is
protecting/releasing objects through a FIFO proxy.


Reading the source (below, from memory.c) I think not, but some
confirmation would help.

I understand the code in memory.c like an object preserved twice needs
to be freed twice: R_PreciousList is just a (linked) list, and
"R_PreserveObject(object)" adds the object to the beginning of the
list while "R_ReleaseObject(object)" removes the first "object" found
from the list.



void R_PreserveObject(SEXP object)
{
R_PreciousList = CONS(object, R_PreciousList);
}

static SEXP RecursiveRelease(SEXP object, SEXP list)
{
if (!isNull(list)) {
if (object == CAR(list))
return CDR(list);
else
CDR(list) = RecursiveRelease(object, CDR(list));
}
return list;
}

void R_ReleaseObject(SEXP object)
{
R_PreciousList = RecursiveRelease(object, R_PreciousList);
}


I'd also be interested if there is some ideas on the relative efficiency
of the preserve/release mechanism compared to PROTECT/UNPROTECT.

PROTECT/UNPROTECT is trading granularity for speed. It is a stack with
only tow operations possible:
- push 1 object into the stack
- pull (unprotect) N last objects from the stack

UNPROTECT_PTR is also possible, which does a linear search through the
stack and unprotects something possibly deep within it. There is also
REPROTECT which allows you to replace an entry within the stack.

Thanks; I've used those when I played with the parser's code (for highlight). It felt slightly harder to use than preserve/release since you have to maintain the protect index, etc ...

I think I'll go as you say below, just maintain my own precious list, the way Preserve/Release does it.

Romain

I would guess that UNPROTECT_PTR is more efficient than RecursiveRelease
because it doesn't use so much stack space when it needs to go deep into
the stack to release, but it is possible the compiler recognizes the
tail recursion and RecursiveRelease is implemented efficiently. In that
case it could be more efficient than UNPROTECT_PTR, which has to move
all the other entries down to fill the newly vacated space. Really the
only reliable way to answer efficiency questions like this is to try
both ways and see which works better in your application.

Another possibility is to maintain your own list or environment of
objects, and just protect/preserve the list as a whole.

Duncan Murdoch

--
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://tr.im/IW9B : C++ exceptions at the R level
|- http://tr.im/IlMh : CPP package: exposing C++ objects
`- http://tr.im/HlX9 : new package : bibtex

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to