[Rcpp-devel] Idiom for accessing scalars

Douglas Bates bates at stat.wisc.edu
Fri Jan 6 19:59:25 CET 2012


On Fri, Jan 6, 2012 at 12:39 PM, John Chambers <jmc at stat.stanford.edu> wrote:
> At the risk of derailing this thread into the quicksand of programming style
> ....
>
> Except when required by the specific application, my preference would be to
> stay with the Rcpp idiom.  Mixing in the older C API seems to risk more
> programming error.  Of course, each application is different and we have to
> make decisions about efficiency (machine) vs possible inefficiency (human).

I would argue that special-purpose functions and macros for handling
the funky C structures are the best way of handling the funky C
structures.   Relative to working with C++ classes and methods they
are clunky but, short of converting to something like CXXR, we are
stuck with the C structures.

> The "Rf_" part of the API in particular is ugly and somewhat of an add-on
> forced in a few examples by the use of some common names in the macro files.

But, as it stands, that is a requirement when using Rcpp.

I think of the Rf_ part as more due to the fact that C doesn't have a
concept of namespaces so anything in the R API is at the top level
namespace leading to some conflicts.

> This year in our Stanford grad course, I'm planning to push Rcpp, so in a
> few months I may have a different view.  :-)
>
> Cheers,
>  John
>
>
> On 1/6/12 10:15 AM, Dirk Eddelbuettel wrote:
>>
>> On 6 January 2012 at 13:00, Steve Lianoglou wrote:
>> | Hi,
>> |
>> | 2012/1/6 Douglas Bates<bates at stat.wisc.edu>:
>> | [snip]
>> |>  As I mentioned in another thread, I prefer the idiom
>> |>
>> |>  int n2 = ::Rf_asInteger(n);
>> |>
>> |>  because asInteger is part of the R API (in Rcpp it must be called as
>> |>  Rf_asInteger - the :: is a hint to the compiler that it will be found
>> |>  in the global namespace).  Functions like asInteger and asReal are
>> |>  used in thousands of places in the base R code and have been optimized
>> |>  to death as well as being as general as they can possibly be.
>> |
>> | Cool ... I actually missed that tip, thanks for pointing it out again.
>>
>> And if one overcomes the "ick" factor of mixing APIs<grin>, it saves a
>> little:
>>
>> R>  library(inline)
>> R>  library(microbenchmark)
>> R>
>> R>  fr<- cxxfunction(signature(xs="integer"), plugin="Rcpp", body='
>> +    int x = ::Rf_asInteger(xs);
>> +    return Rcpp::wrap(x);
>> + ')
>> R>
>> R>  frcpp<- cxxfunction(signature(xs="integer"), plugin="Rcpp", body='
>> +    int x = Rcpp::as<int>(xs);
>> +    return Rcpp::wrap(x);
>> + ')
>> R>
>> R>  microbenchmark(fr(123), frcpp(123))
>> Unit: nanoseconds
>>         expr min    lq median   uq   max
>> 1    fr(123) 841 878.5  908.5  976 15684
>> 2 frcpp(123) 976 999.5 1017.0 1085  6589
>> R>
>>
>> A good chunk here is "fixed" cost of calling a function, returning a
>> value, ... so that the "variable" gain of ::Rf_asInteger() looks pretty
>> good.
>>
>> Dirk, somewhat wondering why we're debating 100ns gains in the context of
>> R
>>
> _______________________________________________
> Rcpp-devel mailing list
> Rcpp-devel at lists.r-forge.r-project.org
> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel


More information about the Rcpp-devel mailing list