On Jan 2, 2010, at 5:07 AM, Romain Francois 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.
>
I don't think so - the only documentation is the comment in the source.
> In particular, if we preserve the same SEXP twice (or more), should we
> implement some sort of reference counting ?
>
Preserve/Release are for managing objects that are supposed to survive past the
call and are not tied to any other R object. PROTECT/UNPROTECT are for
temporary preservation within a call.
Although you're right that Preserve/Release is effectively implemented as a
stack at the moment it is not stated explicitly anywhere (this goes all the way
back to R 0.64 so chances are that only Ross can comment..). However, for
practical purposes it would be potentially dangerous to have it work like a
flag because you can simply never know whether the same object was not already
registered by some other code.
> Reading the source (below, from memory.c) I think not, but some confirmation
> would help.
>
> 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 more efficient because all it does is a pointer assignment
-- Preserve has to allocate new node and fill it with all parts. On release the
extra node is still floating in the GC pool etc.
Normally there is not really a question of choice - within a call you want to
use PROTET/UNPROTECT and for anything else you simply cannot use it so you have
to use Preserve/Release. As a side note Preserve/Release is merely a
convenience call, it is often more efficient to simply assign the object to
another object you have control of (which is all Preserve really does).
Cheers,
Simon
______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel