[Rcpp-devel] speed

Douglas Bates bates at stat.wisc.edu
Wed Aug 4 21:56:01 CEST 2010


On Wed, Aug 4, 2010 at 2:27 PM, Sanjog Misra <misra at simon.rochester.edu> wrote:
> Richard,
>
> I did a quick check and the Rcpp/C++ version is at least twice as fast as
> the pure R code.

I get a similar result.

But a more important question is whether your C++ code is producing
the same values are the R function.  In R your sequence is 0:K[i] but
in C++ your code is

>>             IntegerVector Ki = K[i];
>>             IntegerVector cmin = seq_len(Ki.size()+1);
>>             IntegerVector cmin0 = cmin-1;

Because K is an Integervector, K[i] will be an int and Ki will be an
IntegerVector of length 1.  That is Ki.size() will always be 1 and
cmin0 will be equivalent to the R expression 0:1, not 0:K[i]

There are several other places that the code could be tightened.  For
example, you can avoid the call to the R functions because Rf_dbinom
and Rf_dpois are part of the R API.  Furthermore, the inner loop can
work with scalars instead of vectors if you do the accumulation in a
C++ loop.  Dirk and Romain have done a magnificent job making
different types of R vectors available within C++ but, even so,
operations on C++ native types will always be faster.

But before pursuing that it would be best to straighten out what cmin
and cmin0 should be.  I think they are incorrectly defined.  (Also,
they are loop invariants and their definition, however it is
reconciled, can be moved outside the loop on j.  A smart compiler may
do this but you shouldn't count on that.)

> Best
> Sanjog
>
>
> On 8/4/10 3:21 PM, "Richard Chandler" <richard.chandlers at gmail.com> wrote:
>
>> Hi,
>>
>> I wrote my first Rcpp/C++ program in hopes of speeding up an R
>> function, but alas it is slower. I think the C++ program is slower
>> because I have made heavy use of dbinom and dpois from R. Is there a
>> way to do this without calling back to R? Are there any other obvious
>> ways to speed up the C++ program? I realize that I can vectorize the R
>> function and avoid zero probabilities, but I have showed it this way
>> for simplicity.
>>
>> Thanks,
>> Richard
>>
>>
>>
>> fx <- cxxfunction(signature(Kr="integer"), '
>>     Environment stats("package:stats");
>>     Function dbinom = stats["dbinom"];
>>     Function dpois = stats["dpois"];
>>
>>     IntegerVector K(Kr);
>>     NumericMatrix bpsum(K.size(), K.size());
>>     for(int i=0; i<K.size(); i++) {
>>         for(int j=0; j<K.size(); j++) {
>>             IntegerVector Ki = K[i];
>>             IntegerVector cmin = seq_len(Ki.size()+1);
>>             IntegerVector cmin0 = cmin-1;
>>             NumericVector bin = dbinom(cmin0, K[j], 0.5);
>>             NumericVector pois = dpois(K[j]-cmin0, 1.5);
>>             NumericVector bp = bin * pois;
>>             bpsum(i, j) = std::accumulate(bp.begin(), bp.end(), 0.0);
>>             }
>>         }
>>     return bpsum;
>>     ',  plugin="Rcpp")
>>
>>
>>
>> fxR <- function(K) {
>>     lk <- length(K)
>>     bpsum <- matrix(NA, lk, lk)
>>     for(i in 1:lk)
>>         for(j in 1:lk)
>>             bpsum[i, j] <- sum(dbinom(0:K[i], K[j], 0.5) *
>> dpois(K[j]-(0:K[i]), 1.5))
>>     return(bpsum)
>>     }
>>
>>
>> all.equal(fx(0:10), fxR(0:10))
>> system.time(fx(0:100))
>> system.time(fxR(0:100))
>> _______________________________________________
>> 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
>
> _______________________________________________
> 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