[Rd] suggest that as.double( something double ) not make a copy
Simon Urbanek
simon.urbanek at r-project.org
Thu Jun 7 02:15:57 CEST 2012
On Jun 6, 2012, at 6:53 PM, Tim Hesterberg wrote:
> I've been playing with passing arguments to .C(), and found that replacing
> as.double(x)
> with
> if(is.double(x)) x else as.double(x)
> saves time and avoids one copy, in the case that x is already double.
>
No, it doesn't:
> x=rnorm(10)
> tracemem(x)
[1] "<0x100c59cb0>"
> invisible(.C("foo",x))
tracemem[0x100c59cb0 -> 0x100c59c30]: .C
tracemem[0x100c59c30 -> 0x100ca4298]: .C
> x=rnorm(10)
> tracemem(x)
[1] "<0x100ca41f0>"
> invisible(.C("foo",as.double(x)))
tracemem[0x100ca41f0 -> 0x102cdc980]: .C
tracemem[0x102cdc980 -> 0x102cdca00]: .C
or rather more easily:
> x=rnorm(10)
> tracemem(x)
[1] "<0x102ae0ff0>"
> as.double(x)
[1] -0.1027767 0.4018732 -1.3412045 0.8153615 1.8245356 -0.2147280
[7] 1.1298404 1.1026897 -1.1340612 -0.2346464
as.double(x) is not stupid and doesn't copy if not needed.
However, it is a very common mistake to forget about the fact that as.double() has to strip attributes, so if you pass a matrix, you are always forcing a copy:
> x=matrix(0,2,2)
> tracemem(x)
[1] "<0x100b0f098>"
> as.double(x)
tracemem[0x100b0f098 -> 0x1008b52c8]:
[1] 0 0 0 0
That is not the fault of as.double() but rather of the user since you don't really need to strip attributes when calling .C as it doesn't care.
As usual, I can only say don't use .C() ... ;)
Cheers,
Simon
> I suggest modifying as.double to avoid the extra copy and just
> return x, when x is already double. Similarly for as.integer, etc.
More information about the R-devel
mailing list