Last active
May 16, 2018 02:06
-
-
Save lilywang1988/e2d30db8ba46ed670c0a655093245b65 to your computer and use it in GitHub Desktop.
cxxfunction vs cppFunction
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
cxxfunction vs cppFunction | |
Lili Wang | |
May 4, 2018 | |
Motivation | |
cppFucntion() is by defaut available in Rcpp library; cxxfunction() is from the inline library. Note that, for the latter, you will need to require both Rcpp and inline libraries. Both dynamically define an R function with inlined C++ code using the .Call calling convention. I’m curious about how the two function differ from the other, and which should I choose in practice. | |
For below, I will implement both functions to construct a function in C++ | |
R | |
min_flag_R=function(x){ | |
y=(min(x)<0) | |
return(y) | |
} | |
cppFunction | |
Rcpp in cppFunction | |
library(Rcpp) | |
src<-'bool min_flag_cpp_cpp( NumericVector x){return(min(x)<0);}' | |
cppFunction(src) #cppFunction(src,depends="Rcpp") | |
RcppArmadillo in cppFunction | |
src<-'bool min_flag_cpp_arma( arma::vec x){ | |
return(min(x)<0); | |
}' | |
cppFunction(src,depends="RcppArmadillo")# plugins=c("cpp11") | |
cxxfunction | |
Rcpp in cxxfunction | |
library(inline) | |
## | |
## Attaching package: 'inline' | |
## The following object is masked from 'package:Rcpp': | |
## | |
## registerPlugin | |
src<-' | |
return wrap(min(as<NumericVector>(x))<0); | |
' | |
rcpp_inc <- 'using namespace Rcpp;' | |
min_flag_cxx_cpp<-cxxfunction(signature(x="numeric"),src,plugin = "Rcpp",includes = rcpp_inc) | |
## ld: warning: directory not found for option '-L/usr/local/opt/openssl/lib' | |
# the type in R | |
Armadillo in cxxfunction | |
library(inline) | |
src<-' | |
return(wrap(min(as<vec>(x))<0)); | |
' #need to transform into the type in RcppArmadillo | |
rcpp_inc <- 'using namespace Rcpp; | |
using namespace arma;' | |
min_flag_cxx_arma<-cxxfunction(signature(x="NumericVector"),src,plugin = "RcppArmadillo",includes=rcpp_inc) #input type in R | |
## ld: warning: directory not found for option '-L/usr/local/opt/openssl/lib' | |
Comparison | |
library(rbenchmark) | |
set.seed(100) | |
benchmark("R" = { | |
x <- rnorm(1000) | |
min_flag_R(x) | |
}, | |
"cpp_cpp" = { | |
x <- rnorm(1000) | |
min_flag_cpp_cpp(x) | |
}, | |
"cpp_arma" = { | |
x <- rnorm(1000) | |
min_flag_cpp_arma(x) | |
}, | |
"cxx_cpp" = { | |
x <- rnorm(1000) | |
min_flag_cxx_cpp(x) | |
}, | |
"cxx_arma" = { | |
x <- rnorm(1000) | |
min_flag_cxx_arma(x) | |
}, | |
replications = 1000, | |
order="user.self", | |
columns = c("test", "replications","relative", "user.self","elapsed", | |
"sys.self"), | |
relative = "user.self") | |
## test replications relative user.self elapsed sys.self | |
## 5 cxx_arma 1000 1.000 0.080 0.082 0.001 | |
## 3 cpp_arma 1000 1.012 0.081 0.082 0.000 | |
## 1 R 1000 1.062 0.085 0.088 0.004 | |
## 4 cxx_cpp 1000 1.100 0.088 0.088 0.000 | |
## 2 cpp_cpp 1000 1.300 0.104 0.108 0.003 |
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
--- | |
title: "cxxfunction vs cppFunction" | |
author: "Lili Wang" | |
date: "May 4, 2018" | |
output: html_document | |
--- | |
```{r setup, include=FALSE} | |
knitr::opts_chunk$set(echo = TRUE) | |
``` | |
## Motivation | |
cppFucntion() is by defaut available in Rcpp library; cxxfunction() is from the inline library. Note that, for the latter, you will need to require both Rcpp and inline libraries. Both dynamically define an R function with inlined C++ code using the .Call calling convention. I'm curious about how the two function differ from the other, and which should I choose in practice. | |
For below, I will implement both functions to construct a function in C++ | |
### R | |
```{r rcode} | |
min_flag_R=function(x){ | |
y=(min(x)<0) | |
return(y) | |
} | |
``` | |
### cppFunction | |
#### Rcpp in cppFunction | |
```{r Rcpp cppFuncntion} | |
library(Rcpp) | |
src<-'bool min_flag_cpp_cpp( NumericVector x){return(min(x)<0);}' | |
cppFunction(src) #cppFunction(src,depends="Rcpp") | |
``` | |
#### RcppArmadillo in cppFunction | |
```{r Arma cppFunction} | |
src<-'bool min_flag_cpp_arma( arma::vec x){ | |
return(min(x)<0); | |
}' | |
cppFunction(src,depends="RcppArmadillo")# plugins=c("cpp11") | |
``` | |
## cxxfunction | |
### Rcpp in cxxfunction | |
```{r Rcpp cxxfunction} | |
library(inline) | |
src<-' | |
return wrap(min(as<NumericVector>(x))<0); | |
' | |
rcpp_inc <- 'using namespace Rcpp;' | |
min_flag_cxx_cpp<-cxxfunction(signature(x="numeric"),src,plugin = "Rcpp",includes = rcpp_inc) | |
# the type in R | |
``` | |
### Armadillo in cxxfunction | |
```{r Arma cxxfunction} | |
library(inline) | |
src<-' | |
return(wrap(min(as<vec>(x))<0)); | |
' #need to transform into the type in RcppArmadillo | |
rcpp_inc <- 'using namespace Rcpp; | |
using namespace arma;' | |
min_flag_cxx_arma<-cxxfunction(signature(x="NumericVector"),src,plugin = "RcppArmadillo",includes=rcpp_inc) #input type in R | |
``` | |
## Comparison | |
```{r compare} | |
library(rbenchmark) | |
set.seed(100) | |
benchmark("R" = { | |
x <- rnorm(1000) | |
min_flag_R(x) | |
}, | |
"cpp_cpp" = { | |
x <- rnorm(1000) | |
min_flag_cpp_cpp(x) | |
}, | |
"cpp_arma" = { | |
x <- rnorm(1000) | |
min_flag_cpp_arma(x) | |
}, | |
"cxx_cpp" = { | |
x <- rnorm(1000) | |
min_flag_cxx_cpp(x) | |
}, | |
"cxx_arma" = { | |
x <- rnorm(1000) | |
min_flag_cxx_arma(x) | |
}, | |
replications = 1000, | |
order="user.self", | |
columns = c("test", "replications","relative", "user.self","elapsed", | |
"sys.self"), | |
relative = "user.self") | |
``` | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment