From ripley at stats.ox.ac.uk  Fri Aug 27 16:18:24 2010
From: ripley at stats.ox.ac.uk (Prof Brian Ripley)
Date: Fri, 27 Aug 2010 15:18:24 +0100 (BST)
Subject: [Rd] Is it safe not to coerce matrices with as.double() in .C()?
In-Reply-To: <B70A8DAE-0879-4E71-9792-359CF433240B@gmail.com>
References: <B10BAA7D28D88B45AF82813C4A6FFA93B323DA@usctmx1157.merck.com>
	<B70A8DAE-0879-4E71-9792-359CF433240B@gmail.com>
Message-ID: <alpine.LFD.2.00.1008271510490.30882@localhost>

On Fri, 27 Aug 2010, peter dalgaard wrote:

>
> On Aug 27, 2010, at 2:44 PM, Liaw, Andy wrote:
>
>> I'd very much appreciate guidance on this.  A user reported that the
>> as.double() coercion used inside the .C() call for a function in my
>> package (specifically, randomForest:::predict.randomForest()) is
>> taking up significant amount of time when called repeatedly, and
>> Removing some of these reduced run time by 30-40% in some cases.
>> These arguments are components of the fitted model (thus do not
>> change), and are matrices.  Some basic tests show no difference in
>> The result when the coercions are removed (other than faster run time).
>> What I like to know is whether this is safe to do, or is it likely to
>> lead
>> to trouble in the future?
>
> In a word: yes. It is safe as long as you are absolutely sure that 
> the argument has the right mode. The unsafeness comes in when people 
> might unwittingly use, say, an integer vector where a double was 
> expected, causing memory overruns and general mayhem.
>
> Notice, BTW, that if you switch to .Call or .External, then you have 
> much more scope for handling such details on the C-side. E.g. you 
> could coerce only if the object has the wrong mode, avoid 
> duplicating things you won't be modifying anyway, etc.

But as as.double is effectively .Call it has the same freedom, and it 
does nothing if no coercion is required.  The crunch here is likely to 
be

      ?as.double? attempts to coerce its argument to be of double type:
      like ?as.vector? it strips attributes including names.  (To ensure
      that an object is of double type without stripping attributes, use
      ?storage.mode?.)

I suspect the issue is the copying to remove attributes, in which case

storage.mode(x) <- "double"

should be a null op and so both fast and safe.

-- 
Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595


[Rd] Is it safe not to coerce matrices with as.double() in .C()?
Prof Brian Ripley