3 suppressMessages(library(inline))
4 suppressMessages(library(Rcpp))
6 benchmark <- function(start = settings$start,
7 hand.written = settings$hand.written,
8 sugar = settings$sugar,
16 start = "", hand.written = "",
17 sugar = "", expr = NULL,
29 unsigned int runs = as<int>(runss);
38 for (unsigned int i=0; i<runs; i++) {
42 double t1 = timer.ElapsedTime();
45 timer.Reset(); timer.Start();
46 for (unsigned int i=0; i<runs; i++) {
50 double t2 = timer.ElapsedTime();
54 timer.Reset(); timer.Start();
55 for (unsigned int i=0; i<runs; i++) {
56 NumericVector res2 = Rcpp_fast_eval( call, e ) ;
59 double t3 = timer.ElapsedTime();
63 return NumericVector::create(
64 _["hand written"] = t1,
69 paste( start, collapse = "\n" ) ,
70 paste( hand.written, collapse = "\n" ),
71 paste( sugar, collapse = "\n" ),
72 paste( end, collapse = "\n" )
76 for( i in names(data) ){
77 assign( i, data[[i]], envir = e )
80 settings <- getPlugin("Rcpp")
81 settings$env$PKG_CXXFLAGS <- paste("-I", getwd(), sep="")
83 fun <- cxxfunction(signature(runss="integer", expr = "language", env = "environment" ),
85 includes= sprintf( '#include "Timer.h"\n%s', paste( inc, collapse = "\n" ) ),
88 results <- fun(runs, expr, environment() )
90 list( results = results, runs = runs, expr = deparse(expr) )
93 settings.ifelse <- list( start = '
94 NumericVector x = e["x"] ;
95 NumericVector y = e["y"] ;
98 NumericVector res1( n ) ;
101 for( int i=0; i<n; i++){
104 if( R_IsNA(x_) || R_IsNA(y_) ){
106 } else if( x_ < y_ ){
109 res1[i] = -( y_ * y_) ;
114 NumericVector res2 = ifelse( x < y, x*x, -(y*y) ) ;
115 ', expr = quote(ifelse(x<y, x*x, -(y*y) )),
116 data = list( x = runif(1e5), y = runif(1e5) )
119 settings.ifelse.nona <- list( start = '
120 NumericVector x = e["x"] ;
121 NumericVector y = e["y"] ;
124 NumericVector res1( n ) ;
127 for( int i=0; i<n; i++){
133 res1[i] = -( y_ * y_) ;
138 NumericVector res2 = ifelse( x < y, noNA(x)*noNA(x), -(noNA(y)*noNA(y)) ) ;
139 ', expr = quote(ifelse(x<y, x*x, -(y*y) )),
140 data = list( x = runif(1e5), y = runif(1e5) )
143 settings.sapply <- list( start = '
144 NumericVector x = e["x"] ;
148 NumericVector res1( n ) ;
149 std::transform( x.begin(), x.end(), res1.begin(), square ) ;
152 NumericVector res2 = sapply( x, square ) ;
154 expr = quote(sapply(x,square)),
158 square = function(x) x*x
161 inline double square(double x){ return x*x ; }
165 settings.any <- list( start = '
166 NumericVector x = e["x"] ;
167 NumericVector y = e["y"] ;
173 bool seen_na = false ;
174 bool result = false ;
177 for( int i=0; i<n; i++){
194 res = result ? TRUE : ( seen_na ? NA_LOGICAL : FALSE ) ;
196 res2 = any( x*y < 0 ) ;
198 expr = quote(any(x*y<0)),
201 x = seq( -1, 1, length = 1e05),
206 benchmark( settings = settings.any , runs = 5000 ),
207 benchmark( settings = settings.ifelse, runs = 500 ),
208 benchmark( settings = settings.ifelse.nona, runs = 500 ),
209 benchmark( settings = settings.sapply, runs = 500 )
213 results <- do.call( rbind, lapply( raw.results, "[[", "results" ) )
214 results <- data.frame(
215 runs = sapply( raw.results, "[[", "runs" ),
216 expr = sapply( raw.results, "[[", "expr" ),
217 as.data.frame( results, stringsAsFactors = FALSE )
220 results[[ "hand/sugar" ]] <- results[["hand.written" ]] / results[["sugar"]]
221 results[[ "R/sugar" ]] <- results[["R" ]] / results[["sugar"]]
222 # results <- results[ order( results[["expr"]], results[["runs"]] ), ]
224 options( width = 300 )