|
Rcpp Version 0.9.10
|
00001 #!/usr/bin/r 00002 00003 library(inline) 00004 library(rbenchmark) 00005 00006 serialCode <- ' 00007 // assign to C++ vector 00008 std::vector<double> x = Rcpp::as<std::vector< double > >(xs); 00009 size_t n = x.size(); 00010 for (size_t i=0; i<n; i++) { 00011 x[i] = ::log(x[i]); 00012 } 00013 return Rcpp::wrap(x); 00014 ' 00015 funSerial <- cxxfunction(signature(xs="numeric"), body=serialCode, plugin="Rcpp") 00016 00017 serialStdAlgCode <- ' 00018 std::vector<double> x = Rcpp::as<std::vector< double > >(xs); 00019 std::transform(x.begin(), x.end(), x.begin(), ::log); 00020 return Rcpp::wrap(x); 00021 ' 00022 funSerialStdAlg <- cxxfunction(signature(xs="numeric"), body=serialStdAlgCode, plugin="Rcpp") 00023 00024 ## same, but with Rcpp vector just to see if there is measurable difference 00025 serialRcppCode <- ' 00026 // assign to C++ vector 00027 Rcpp::NumericVector x = Rcpp::NumericVector(xs); 00028 size_t n = x.size(); 00029 for (size_t i=0; i<n; i++) { 00030 x[i] = ::log(x[i]); 00031 } 00032 return x; 00033 ' 00034 funSerialRcpp <- cxxfunction(signature(xs="numeric"), body=serialRcppCode, plugin="Rcpp") 00035 00036 serialStdAlgRcppCode <- ' 00037 Rcpp::NumericVector x = Rcpp::NumericVector(xs); 00038 std::transform(x.begin(), x.end(), x.begin(), ::log); 00039 return x; 00040 ' 00041 funSerialStdAlgRcpp <- cxxfunction(signature(xs="numeric"), body=serialStdAlgRcppCode, plugin="Rcpp") 00042 00043 serialImportTransRcppCode <- ' 00044 Rcpp::NumericVector x(xs); 00045 return Rcpp::NumericVector::import_transform(x.begin(), x.end(), ::log); 00046 ' 00047 funSerialImportTransRcpp <- cxxfunction(signature(xs="numeric"), body=serialImportTransRcppCode, plugin="Rcpp") 00048 00049 ## now with a sugar expression with internalizes the loop 00050 sugarRcppCode <- ' 00051 // assign to C++ vector 00052 Rcpp::NumericVector x = log ( Rcpp::NumericVector(xs) ); 00053 return x; 00054 ' 00055 funSugarRcpp <- cxxfunction(signature(xs="numeric"), body=sugarRcppCode, plugin="Rcpp") 00056 00057 ## lastly via OpenMP for parallel use 00058 openMPCode <- ' 00059 // assign to C++ vector 00060 std::vector<double> x = Rcpp::as<std::vector< double > >(xs); 00061 size_t n = x.size(); 00062 #pragma omp parallel for shared(x, n) 00063 for (size_t i=0; i<n; i++) { 00064 x[i] = ::log(x[i]); 00065 } 00066 return Rcpp::wrap(x); 00067 ' 00068 00069 ## modify the plugin for Rcpp to support OpenMP 00070 settings <- getPlugin("Rcpp") 00071 settings$env$PKG_CXXFLAGS <- paste('-fopenmp', settings$env$PKG_CXXFLAGS) 00072 settings$env$PKG_LIBS <- paste('-fopenmp -lgomp', settings$env$PKG_LIBS) 00073 00074 funOpenMP <- cxxfunction(signature(xs="numeric"), body=openMPCode, plugin="Rcpp", settings=settings) 00075 00076 00077 z <- seq(1, 2e6) 00078 res <- benchmark(funSerial(z), funSerialStdAlg(z), 00079 funSerialRcpp(z), funSerialStdAlgRcpp(z), 00080 funSerialImportTransRcpp(z), 00081 funOpenMP(z), funSugarRcpp(z), 00082 columns=c("test", "replications", "elapsed", 00083 "relative", "user.self", "sys.self"), 00084 order="relative", 00085 replications=100) 00086 print(res) 00087 00088