You can make the differences more profound if you choose examples
where range.default does really badly (assuming your implementation is
similar to my attached implementation)

                   expr  min   lq median   uq   max neval
 range(x, na.rm = TRUE) 1920 2488   2951 3349 23306   100
   min(x, na.rm = TRUE)  251  252    259  266   301   100
   max(x, na.rm = TRUE)  251  251    258  267   301   100
        range2(x, TRUE)  149  150    156  162   185   100
        range3(x, TRUE)  153  155    160  170   224   100
       range3a(x, TRUE)  462  465    477  492   794   100

Unit: microseconds
                    expr    min     lq median     uq     max neval
 range(x, na.rm = FALSE) 695.16 703.54 722.01 947.89 1875.59   100
   min(x, na.rm = FALSE) 251.10 251.26 251.49 262.27  581.50   100
   max(x, na.rm = FALSE) 251.11 251.27 251.56 258.65  329.30   100
        range2(x, FALSE)   1.42   1.75   2.11   3.27    6.48   100
        range3(x, FALSE)   1.39   1.67   2.13   2.90   16.42   100
       range3a(x, FALSE)   1.42   1.80   2.33   2.98   21.32   100

Hadley


-- 
RStudio / Rice University
http://had.co.nz/

Attachment: range.r
Description: Binary data

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector range2(NumericVector x, const bool na_rm) {
  NumericVector out(2);
  out[0] = R_PosInf;
  out[1] = R_NegInf;

  int n = x.length();
  for(int i = 0; i < n; ++i) {
    if (!na_rm && R_IsNA(x[i])) {
      out[0] = NA_REAL;
      out[1] = NA_REAL;
      return(out);
    }

    if (x[i] < out[0]) out[0] = x[i];
    if (x[i] > out[1]) out[1] = x[i];
  }

  return(out);

}

// Iterators - the right way (but no faster than raw access)
// [[Rcpp::export]]
NumericVector range3(NumericVector x, const bool na_rm) {
  NumericVector out(2);
  out[0] = R_PosInf;
  out[1] = R_NegInf;

  NumericVector::iterator it;
  NumericVector::iterator end = x.end();
  for(it = x.begin(); it != end; ++it) {
    double val = *it;
    if (!na_rm && R_IsNA(val)) {
      out[0] = NA_REAL;
      out[1] = NA_REAL;
      return(out);
    }

    if (val < out[0]) out[0] = val;
    if (val > out[1]) out[1] = val;
  }

  return(out);

}

// Iterators - the _really_ right way but much slower
// [[Rcpp::export]]
NumericVector range3a(const NumericVector& x, const bool na_rm) {
  NumericVector out(2);
  out[0] = R_PosInf;
  out[1] = R_NegInf;

  NumericVector::iterator it;
  for(it = x.begin(); it != x.end(); ++it) {
    double val = *it;
    if (!na_rm && R_IsNA(val)) {
      out[0] = NA_REAL;
      out[1] = NA_REAL;
      return(out);
    }

    if (val < out[0]) out[0] = val;
    if (val > out[1]) out[1] = val;
  }

  return(out);
}
_______________________________________________
Rcpp-devel mailing list
[email protected]
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel

Reply via email to