From hb at biostat.ucsf.edu  Thu Jun  7 04:10:22 2012
From: hb at biostat.ucsf.edu (Henrik Bengtsson)
Date: Wed, 6 Jun 2012 19:10:22 -0700
Subject: [Rd] suggest that as.double( something double ) not make a copy
In-Reply-To: <loom.20120607T024354-968@post.gmane.org>
References: <CAAWNEwaLpwLxT58B6PAXm7r=S9fnSjKUB3xT1XrrFMwQgYzDMw@mail.gmail.com>
	<loom.20120607T024354-968@post.gmane.org>
Message-ID: <CAFDcVCQEnzPns2Z4O8=T0X5OnCxcDir=3utRvHhLOwweqqxisQ@mail.gmail.com>

Check if this is the same as what was done in R v2.6.0 (2007) - from
http://cran.r-project.org/bin/windows/base/old/2.6.0/NEWS.R-2.6.0:

    o	as.vector() and the default methods of as.character(),
	as.complex(), as.double(), as.expression(), as.integer(),
	as.logical() and as.raw() no longer duplicate in most cases
	where the object is unchanged.  (Beware: some code has been
	written that invalidly assumes that they do duplicate, often
	when using .C/.Fortran(DUP=FALSE).)

See also R-devel '[Rd] Suggestion for memory optimization and
as.double() with friends', March 28-29 2007
[https://stat.ethz.ch/pipermail/r-devel/2007-March/045109.html].

/Henrik


On Wed, Jun 6, 2012 at 6:12 PM, Matthew Dowle <mdowle at mdowle.plus.com> wrote:
> Tim Hesterberg <timhesterberg <at> gmail.com> writes:
>
>> 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.
>>
>> I suggest modifying as.double to avoid the extra copy and just
>> return x, when x is already double. Similarly for as.integer, etc.
>>
>
> But as.double() already doesn't copy if its argument is already double. Unless,
> your double has attributes?
>
> >From coerce.c :
>
> if(TYPEOF(x) == type) {
> ? ?if(ATTRIB(x) == R_NilValue) return x;
> ? ?ans = NAMED(x) ? duplicate(x) : x;
> ? ?CLEAR_ATTRIB(ans);
> ? ?return ans;
> }
>
> quick test :
>
>> x=1
>> .Internal(inspect(x))
> @0000000003E23620 14 REALSXP g0c1 [NAM(2)] (len=1, tl=0) 1
>> .Internal(inspect(as.double(x))) ? # no copy
> @0000000003E23620 14 REALSXP g0c1 [NAM(2)] (len=1, tl=0) 1
>> x=c(foo=1) ? # give x some attributes, say names
>> x
> foo
> ?1
>> .Internal(inspect(x))
> @0000000003E234D0 14 REALSXP g0c1 [NAM(1),ATT] (len=1, tl=0) 1
> ATTRIB:
> ?@0000000003D54910 02 LISTSXP g0c0 []
> ? ?TAG: @0000000000380088 01 SYMSXP g0c0 [MARK,gp=0x4000] "names"
> ? ?@0000000003E234A0 16 STRSXP g0c1 [NAM(2)] (len=1, tl=0)
> ? ? ?@0000000003E23560 09 CHARSXP g0c1 [gp=0x21] "foo"
>> .Internal(inspect(as.double(x))) ? # strips attribs returning new obj
> @0000000003E233B0 14 REALSXP g0c1 [] (len=1, tl=0) 1
>> as.double(x)
> [1] 1
>>
>
> Attribute stripping is documented in ?as.double. Rather than as.double() on the
> R side, you could use coerceVector() on the C side, which might be easier to
> use via .Call than .C since it takes an SEXP. Looking at coerceVector in
> coerce.c its first line returns immediately if type is already the desired
> type, with no attribute stripping, so that seems like the way to go?
>
> If your double has no attributes then I'm barking up the wrong tree.
>
> Matthew
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] suggest that as.double( something double ) not make a copy
Henrik Bengtsson