From simon.urbanek at r-project.org  Mon Oct  3 23:31:08 2011
From: simon.urbanek at r-project.org (Simon Urbanek)
Date: Mon, 3 Oct 2011 17:31:08 -0400
Subject: [Rd] number of copies
In-Reply-To: <1317667429.979.55.camel@nemo>
References: <1317652357.979.25.camel@nemo>
	<7182A7C5-0FAC-423D-8B97-B84DCD623408@r-project.org>
	<1317658585.979.48.camel@nemo>
	<873E1DFD-610E-4683-8633-78FC55507A62@r-project.org>
	<1317667429.979.55.camel@nemo>
Message-ID: <EC695904-C0DC-49DA-9F8D-F2EA071A6E62@r-project.org>


On Oct 3, 2011, at 2:43 PM, Terry Therneau wrote:

> 
> On Mon, 2011-10-03 at 12:31 -0400, Simon Urbanek wrote:
>>> Thanks.  I was hoping that x[,sorted] would act like "double(n)"
>> does in a .C call, and have no extra copies made since it has no local
>> assignment.
>> 
>> Yes it does act the same way, you get an extra copy with double(n) as
>> well - there is no difference.
>> 
> 
> That is surprising.  This is not true of Splus.  Since Chambers mentions it as a specific case as well (Programming with Data, p421) I assumed that R would be at least as intellegent.  He also used the unset() function to declare that something could be treated like double(n), i.e., need no further copies. But that always looked like a dangerous assertion to me and unset has disappeared, perhaps deservedly, from R.
> 

Ok, let me clarify - there are two entirely separate issues: one issue is to avoid duplication of closure arguments in the duplicate() sense -- and that has to do with the reference count and closures in general. The other is duplication in the .C() call which is entirely separate.

If you call
.C("foo", double(n))
then the double(n) object doesn't get duplicated in the call, because it has no references [other than the frame], so there is no duplicate() call on it, but .C will still create a duplicate double* object to pass to the C function because of DUP=TRUE. Then a new R object is created for the result from that double* array.

For comparison, in .Call you would use allocVector(REALSXP, n) and thus avoid two copies.

You can try to avoid that with .C(..., DUP=FALSE) but you'll be treading on eggs, because you can't check NAMED or call duplicate() yourself in C code for cases that may need it, so have to be very, very careful to not modify something inadvertently (this has been a known source of bugs that are hard to track, that's why DUP=FALSE is flagged as dangerous in bold face).

Cheers,
Simon



[Rd] number of copies
Simon Urbanek