Skip to content

Instantly share code, notes, and snippets.

@lilywang1988
Last active May 16, 2018 02:06
Show Gist options
  • Save lilywang1988/e2d30db8ba46ed670c0a655093245b65 to your computer and use it in GitHub Desktop.
Save lilywang1988/e2d30db8ba46ed670c0a655093245b65 to your computer and use it in GitHub Desktop.
cxxfunction vs cppFunction
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
---
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