使用 cppFunction 的内联函数

用 Rcpp 优化 R 代码

Romain François

Consulting Datactive, ThinkR

evalCpp 的局限

evalCpp("40 + 2")
42
evalCpp("PI")
3.141593
evalCpp("exp(1)")
2.718282
用 Rcpp 优化 R 代码

cppFunction

cppFunction() 定义一个 C++ 函数

library(Rcpp)
cppFunction("int fun(){
   int x = 37 ;
   return x ;
}" )

从 R 调用该函数

fun()
37
用 Rcpp 优化 R 代码
cppFunction("int fun(){
   int x = 37 ;
   return x ;
}", verbose = TRUE )
为函数定义生成的代码:
 ------------------------------------------------------
#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
int fun(){
  int x = 37 ;
  return x ;
}

生成的 extern "C" 函数
 -----------------------------------------------------
#include <Rcpp.h>
// fun
int fun();
RcppExport SEXP sourceCpp_1_fun() {
BEGIN_RCPP
    Rcpp::RObject rcpp_result_gen;
    Rcpp::RNGScope rcpp_rngScope_gen;
    rcpp_result_gen = Rcpp::wrap(fun());
    return rcpp_result_gen;
END_RCPP
}
用 Rcpp 优化 R 代码
生成的 R 函数
 -----------------------------------------------

`.sourceCpp_1_DLLInfo` <- dyn.load('/private/var/folders/r_/1b2gjtsd7j92jbbpz4t7ps340000gn/T
/Rtmpl8dL6H/sourceCpp-x86_64-apple-darwin15.6.0-0.12.16/sourcecpp_4bb22c766031/sourceCpp_2.so')

fun <- Rcpp:::sourceCppFunction(function() {}, FALSE, `.sourceCpp_1_DLLInfo`, 'sourceCpp_1_fun')

rm(`.sourceCpp_1_DLLInfo`)

构建共享库
 ----------------------------------------------------

DIR: /private/var/folders/r_/1b2gjtsd7j92jbbpz4t7ps340000gn/T/Rtmpl8dL6H/sourceCpp-x86_64-
apple-darwin15.6.0-0.12.16/sourcecpp_4bb22c766031

/Library/Frameworks/R.framework/Resources/bin/R CMD SHLIB -o 'sourceCpp_2.so'  'file4bb247d077c.cpp'  
clang++  -I/Library/Frameworks
/R.framework/Resources/include -DNDEBUG   -I"/Library/Frameworks/R.framework/Versions/3.4/
Resources/library/Rcpp/include" -I"/private/var/folders/r_/1b2gjtsd7j92jbbpz4t7ps340000gn/
T/Rtmpl8dL6H/sourceCpp-x86_64-apple-darwin15.6.0-0.12.16" -I/usr/local/include   -fPIC  
-Wno-unused-result -Wno-c++11-inline
-namespace -O3 -c file4bb247d077c.cpp -o file4bb247d077c.o
clang++ -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module 
-multiply_defined suppress -L/Library/Frameworks/R.framework/Resources/lib -L/usr/local/lib
-o sourceCpp_2.so file4bb247d077c.o -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework 
-Wl,CoreFoundation
用 Rcpp 优化 R 代码

cppFunction

cppFunction() 定义一个 C++ 函数

library(Rcpp)
cppFunction("int fun(){
   int x = 37 ;
   return x ;
}" )

从 R 调用该函数。

fun()
37
用 Rcpp 优化 R 代码

R 是动态类型

x <- "hello"
x
typeof(x)
"hello"

"character"
x <- 42L
x
typeof(x)
42

"integer"

C++ 是静态类型。

// 将 x 定义为 double

double x = 42.0 ;

// 不能再将其重定义为 int
// ----> 将无法编译

int x = 14 ;
用 Rcpp 优化 R 代码

函数参数与返回值的类型声明

    参数 x 和 y 的类型:double
               |         |
               v         v
double add( double x, double y ){

    // 函数体
    // ...

}
用 Rcpp 优化 R 代码

函数参数与返回值的类型声明

 返回类型:double
   |
   v  
double add( double x, double y ){

    // 函数体
    // ...
    // ...
}
用 Rcpp 优化 R 代码

函数参数与返回值的类型声明

 返回类型:double
  |
  |  函数名:add
  |   |
  |   |    参数 x 和 y 的类型:double
  |   |      |         |
  v   v      v         v
double add( double x, double y ){

    // 函数体
    // ...
    // ...
}
用 Rcpp 优化 R 代码

加法示例

用于相加两个 double 的 C++ 函数。

cppFunction( "
double add( double x, double y){ 
    double res = x + y ; 
    return res ;}
" )
add( 30, 12 ) 

等价的 R 代码

addr <- function(x, y) {
    res <- x + y
    res}
用 Rcpp 优化 R 代码

让我们来练习!

用 Rcpp 优化 R 代码

Preparing Video For Download...