[Rcpp-devel] Rcpp speed

romain at r-enthusiasts.com romain at r-enthusiasts.com
Tue Dec 21 16:31:50 CET 2010


Hello, 

I think the most relevant aspect of the time difference is coercion: 

> x <- 1:10
> typeof(x)
[1] "integer"

So, the constructor of NumericVector has to make a coercion, this is what costs time. As the vector get bigger, the time to coerce them to numeric vectors gets bigger. 

The differences are much less dramatic once you do one of these: 
- coerce x to a REALSXP before you get started
- operate on INTSXP


With this code: 


require(Rcpp)
require(inline)
code <- '
NumericVector xx(x);
NumericVector yy(y);
NumericVector zz = xx + yy;
return( zz );
' 
testfun_Rcpp <- cxxfunction(signature(x="numeric", y="numeric"),
    body = code, plugin="Rcpp")
testfun_R  <- function(x,y) x+y

x <- 1:3
y <- 10 * x
testfun_Rcpp(x, y)

library(rbenchmark)
x <- as.numeric(1:10)
benchmark(replications = 10000, 
    R = testfun_R(x,x), 
    Rcpp = testfun_Rcpp(x, x)
    )

x <- as.numeric(1:1000)
benchmark(replications = 10000, 
    R = testfun_R(x,x), 
    Rcpp = testfun_Rcpp(x, x) 
)

x <- as.numeric(1:1000000)
benchmark(replications = 10000, 
    R = testfun_R(x,x), 
    Rcpp = testfun_Rcpp(x, x) 
)


I get these results: 

  test replications elapsed relative user.self sys.self user.child sys.child
1    R        10000   0.050     1.00     0.049    0.001          0         0
2 Rcpp        10000   0.067     1.34     0.065    0.002          0         0
  test replications elapsed relative user.self sys.self user.child sys.child
1    R        10000   0.087 1.000000     0.083    0.004          0         0
2 Rcpp        10000   0.145 1.666667     0.145    0.000          0         0
  test replications elapsed relative user.self sys.self user.child sys.child
1    R        10000  49.189 1.000000    35.405   13.776          0         0
2 Rcpp        10000 100.849 2.050235    87.029   13.814          0         0


However, it is still true that the bigger x is, the bigger the ratio Rcpp / R gets. Not sure why. Sounds like a nice xmas activity. 

It might be worth looping internally for the benchmark to dilute some of the confusion factor that might be related to inline/rbenchmark. 

Romain


Le 21/12/10 15:15, Gabor Grothendieck a écrit :
> Can anyone explain these results?   Rcpp takes 30% more time than R
> with 10 elements, the same time as R with 1000 elements and 7x as long
> with a million elements.  I would have expected the ratio to be
> highest for `10 elements since that would be dominated by the call
> sequence but its the other way around and it seems to get relatively
> less efficient as the size of the vector grows.
> 
>> require(inline)
>> testfun<- cxxfunction(signature(x="numeric", y="numeric"),
> + body = '
> + NumericVector xx(x);
> + NumericVector yy(y);
> + NumericVector zz = xx + yy;
> + return( zz );
> + ', plugin="Rcpp")
>> x<- 1:3
>> y<- 10 * x
>> testfun(x, y)
> [1] 11 22 33
>>
>> library(rbenchmark)
>> x<- 1:10
>> benchmark(replications = 10000, R = x + x, Rcpp = testfun(x, x))
>    test replications elapsed relative user.self sys.self user.child sys.child
> 1    R        10000    0.17 1.000000      0.16        0         NA        NA
> 2 Rcpp        10000    0.22 1.294118      0.23        0         NA        NA
>>
>> x<- 1:1000
>> benchmark(R = x + x, Rcpp = testfun(x, x))
>    test replications elapsed relative user.self sys.self user.child sys.child
> 1    R          100    0.00        0      0.00        0         NA        NA
> 2 Rcpp          100    0.01        1      0.01        0         NA        NA
>>
>> x<- 1:1000000
>> benchmark(R = x + x, Rcpp = testfun(x, x))
>    test replications elapsed relative user.self sys.self user.child sys.child
> 1    R          100    2.34 1.000000      1.81     0.15         NA        NA
> 2 Rcpp          100   16.64 7.111111     12.63     1.66         NA        NA
> 
> 





More information about the Rcpp-devel mailing list