感谢 user1981275、Dirk Eddelbuettel 和 Romain Francois 的回复。下面是我如何编译 C++ 文件并创建 *.dll,然后在内部调用并使用该 *.dll 文件R
.
步骤 1. 我创建了一个名为“c:\users\mmiller21\myrpackages”的新文件夹,并将文件“logabs2.cpp”粘贴到该新文件夹中。文件“logabs2.cpp”是按照我原来的帖子中所述创建的。
步骤 2. 在新文件夹中我创建了一个新的R
名为“logabs2”的包使用R
我编写的文件名为“新包创建.r”。 “新包创建.r”的内容是:
setwd('c:/users/mmiller21/myrpackages/')
library(Rcpp)
Rcpp.package.skeleton("logabs2", example_code = FALSE, cpp_files = c("logabs2.cpp"))
我发现上面的语法Rcpp.package.skeleton
在 Hadley Wickham 的网站之一上:https://github.com/hadley/devtools/wiki/Rcpp https://github.com/hadley/devtools/wiki/Rcpp
步骤 3. 我安装了新的R
包“logabs2”在R
在 DOS 命令窗口中使用以下行:
C:\Program Files\R\R-3.0.1\bin\x64>R CMD INSTALL -l c:\users\mmiller21\documents\r\win-library\3.0\ c:\users\mmiller21\myrpackages\logabs2
where:
rcmd.exe 文件的位置是:
C:\Program Files\R\R-3.0.1\bin\x64>
安装位置R
我电脑上的软件包是:
c:\users\mmiller21\documents\r\win-library\3.0\
以及我的新位置R
安装之前的包是:
c:\users\mmiller21\myrpackages\
DOS 命令窗口中使用的语法是通过反复试验发现的,可能并不理想。在某些时候,我将“logabs2.cpp”的副本粘贴到“C:\Program Files\R\R-3.0.1\bin\x64>”中,但我认为这并不重要。
步骤 4. 安装新版本后R
包我使用运行它R
我在“c:/users/mmiller21/myrpackages/”文件夹中将其命名为“new package use.r”(尽管我认为该文件夹并不重要)。 ‘new package use.r’的内容是:
library(logabs2)
logabs2(seq(-5, 5, by=2))
输出是:
# [1] 1.609438 1.098612 0.000000 0.000000 1.098612 1.609438
该文件加载了包Rcpp
不用我问。
在这种情况下基R
假设我正确执行了此操作,速度会更快。
#> microbenchmark(logabs2(seq(-5, 5, by=2)), times = 100)
#Unit: microseconds
# expr min lq median uq max neval
# logabs2(seq(-5, 5, by = 2)) 43.086 44.453 50.6075 69.756 190.803 100
#> microbenchmark(log(abs(seq(-5, 5, by=2))), times=100)
#Unit: microseconds
# expr min lq median uq max neval
# log(abs(seq(-5, 5, by = 2))) 38.298 38.982 39.666 40.35 173.023 100
但是,使用 dll 文件比调用外部 cpp 文件更快:
system.time(
cppFunction("
NumericVector logabs(NumericVector x) {
return log(abs(x));
}
")
)
# user system elapsed
# 0.06 0.08 5.85
尽管在本例中,基本 R 似乎更快或与 *.dll 文件一样快,但我毫不怀疑将 *.dll 文件与Rcpp
会比基础更快R
在多数情况下。
这是我第一次尝试创建 R 包或使用 Rcpp,毫无疑问我没有使用最有效的方法。另外,我对这篇文章中的任何印刷错误表示歉意。
EDIT
在下面的评论中,我认为 Romain Francois 建议我将 *.cpp 文件修改为以下内容:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector logabs(NumericVector x) {
return log(abs(x));
}
并重新创建我的R
包,我现在已经完成了。然后我比较了基础R
使用以下代码针对我的新包:
library(logabs)
logabs(seq(-5, 5, by=2))
log(abs(seq(-5, 5, by=2)))
library(microbenchmark)
microbenchmark(logabs(seq(-5, 5, by=2)), log(abs(seq(-5, 5, by=2))), times = 100000)
Base R
仍然快一点或者没有什么不同:
Unit: microseconds
expr min lq median uq max neval
logabs(seq(-5, 5, by = 2)) 42.401 45.137 46.505 69.073 39754.598 1e+05
log(abs(seq(-5, 5, by = 2))) 37.614 40.350 41.718 62.234 3422.133 1e+05
也许这是因为基地R
已经矢量化了。我怀疑有更复杂的功能基础R
会慢很多。或者也许我仍然没有使用最有效的方法,或者也许我只是在某个地方犯了错误。