From mdowle at mdowle.plus.com  Thu Jun  7 03:12:36 2012
From: mdowle at mdowle.plus.com (Matthew Dowle)
Date: Thu, 7 Jun 2012 01:12:36 +0000
Subject: [Rd] suggest that as.double( something double ) not make a copy
References: <CAAWNEwaLpwLxT58B6PAXm7r=S9fnSjKUB3xT1XrrFMwQgYzDMw@mail.gmail.com>
Message-ID: <loom.20120607T024354-968@post.gmane.org>

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



[Rd] suggest that as.double( something double ) not make a copy
Matthew Dowle