Created
December 20, 2012 11:44
-
-
Save krlmlr/4344844 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library( compiler ) | |
library( microbenchmark ) | |
library( inline ) | |
in.interval1 <- function(x, lo, hi) (x > lo & x < hi) | |
in.interval2 <- cmpfun( in.interval1 ) | |
in.interval3 <- function(x, lo, hi) findInterval(x, c(lo, hi)) == 1 | |
in.interval4 <- function(x, lo, hi) !is.na(.bincode(x, c(lo, hi))) | |
in.interval5 <- rcpp( signature(x="numeric", lo="numeric", hi="numeric"), ' | |
NumericVector xx(x); | |
double lower = Rcpp::as<double>(lo); | |
double upper = Rcpp::as<double>(hi); | |
LogicalVector res(xx); | |
for( int i=0; i < res.size(); i++ ) { | |
res[i] = (xx[i] > lower) & (xx[i] < upper); | |
} | |
return Rcpp::wrap( res ); | |
') | |
in.interval6 <- rcpp( signature(x="numeric", lo="numeric", hi="numeric"), ' | |
NumericVector xx(x); | |
double lower = Rcpp::as<double>(lo); | |
double upper = Rcpp::as<double>(hi); | |
LogicalVector res(xx); | |
for( int i=0; i < res.size(); i++ ) { | |
res[i] = xx[i] > lower && xx[i] < upper; | |
} | |
return Rcpp::wrap( res ); | |
') | |
in.interval7 <- function(x, lo, hi) abs(x-(hi+lo)/2)-(hi-lo)/2 < 0 | |
in.interval8 <- rcpp( signature(x="numeric", lo="numeric", hi="numeric"), ' | |
NumericVector xx(x); | |
double lower = Rcpp::as<double>(lo); | |
double upper = Rcpp::as<double>(hi); | |
double sub1 = (upper + lower) / 2.0; | |
double sub2 = (upper - lower) / 2.0; | |
LogicalVector res(xx); | |
for( int i=0; i < res.size(); i++ ) { | |
res[i] = fabs(xx[i] - sub1) < sub2; | |
} | |
return Rcpp::wrap( res ); | |
') | |
TESTSAMPLESIZE <- 1e3 | |
x <- runif(TESTSAMPLESIZE) | |
lo <- 0 | |
hi <- 0.5 | |
b <- in.interval1(x, lo, hi) | |
stopifnot(any(b)) | |
stopifnot(any(!b)) | |
stopifnot(identical(b, in.interval2(x, lo, hi))) | |
stopifnot(identical(b, in.interval3(x, lo, hi))) | |
stopifnot(identical(b, in.interval4(x, lo, hi))) | |
stopifnot(identical(b, in.interval5(x, lo, hi))) | |
stopifnot(identical(b, in.interval6(x, lo, hi))) | |
stopifnot(identical(b, in.interval7(x, lo, hi))) | |
stopifnot(identical(b, in.interval8(x, lo, hi))) | |
SAMPLESIZE <- 1e6 | |
x <- runif(SAMPLESIZE) | |
lo <- 0 | |
hi <- 0.5 | |
microbenchmark( | |
in.interval1(x, lo, hi), | |
in.interval2(x, lo, hi), | |
in.interval3(x, lo, hi), | |
in.interval4(x, lo, hi), | |
in.interval5(x, lo, hi), | |
in.interval6(x, lo, hi), | |
in.interval7(x, lo, hi), | |
in.interval8(x, lo, hi), | |
times=3 | |
) | |
x <- rnorm(SAMPLESIZE) | |
lo <- -0.5 | |
hi <- 0.5 | |
microbenchmark( | |
in.interval1(x, lo, hi), | |
in.interval2(x, lo, hi), | |
in.interval3(x, lo, hi), | |
in.interval4(x, lo, hi), | |
in.interval5(x, lo, hi), | |
in.interval6(x, lo, hi), | |
in.interval7(x, lo, hi), | |
in.interval8(x, lo, hi), | |
times=3 | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
all: results.log | |
results.log: benchmark.R Makefile | |
r -p benchmark.R | tee results.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Unit: milliseconds | |
expr min lq median uq max | |
1 in.interval1(x, lo, hi) 37.17666 38.42437 39.67208 41.09402 42.51595 | |
2 in.interval2(x, lo, hi) 37.40908 37.40916 37.40923 60.05991 82.71058 | |
3 in.interval3(x, lo, hi) 38.50727 39.60490 40.70253 67.27891 93.85530 | |
4 in.interval4(x, lo, hi) 19.78177 21.85969 23.93762 25.05246 26.16730 | |
5 in.interval5(x, lo, hi) 15.18608 15.73077 16.27546 41.53891 66.80235 | |
6 in.interval6(x, lo, hi) 15.22456 16.31206 17.39956 40.49614 63.59272 | |
7 in.interval7(x, lo, hi) 27.82003 50.75206 73.68408 98.93059 124.17711 | |
8 in.interval8(x, lo, hi) 16.28154 16.30808 16.33462 16.34517 16.35571 | |
Unit: milliseconds | |
expr min lq median uq max | |
1 in.interval1(x, lo, hi) 38.98638 39.66520 40.34402 40.75315 41.16228 | |
2 in.interval2(x, lo, hi) 42.10256 42.23833 42.37410 42.92669 43.47928 | |
3 in.interval3(x, lo, hi) 45.34348 46.88152 48.41956 70.01567 91.61178 | |
4 in.interval4(x, lo, hi) 19.60766 21.77997 23.95228 24.57502 25.19776 | |
5 in.interval5(x, lo, hi) 15.21367 15.24321 15.27276 15.78392 16.29508 | |
6 in.interval6(x, lo, hi) 19.13099 19.15701 19.18302 21.32998 23.47694 | |
7 in.interval7(x, lo, hi) 32.75138 33.10463 33.45789 34.24936 35.04084 | |
8 in.interval8(x, lo, hi) 15.16925 15.74474 16.32023 16.86394 17.40766 |
in line 8 compare to integer 1L; do a better job of replication e.g., times=100
This is a C implementation, without checks on type or length of arguments. Also, in.interval7 can be optimized by moving (hi - lo) /2
to the other side of the inequality.
in.interval_c <- cfunction(c(x="numeric", lo="numeric", hi="numeric"),
' int len = Rf_length(x);
double lower = REAL(lo)[0], upper = REAL(hi)[0],
*xp = REAL(x);
SEXP out = PROTECT(NEW_LOGICAL(len));
int *outp = LOGICAL(out);
for (int i = 0; i < len; ++i)
outp[i] = (xp[i] - lower) * (xp[i] - upper) <= 0;
UNPROTECT(1);
return out;')
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Try:
instead of the
return
call at the end (as well as the un-necessary assignment ofres
I had before)