C++ 运行编译的C++;带Rcpp的代码
我一直在学习Dirk Eddelbuettel的C++ 运行编译的C++;带Rcpp的代码,c++,r,rcpp,C++,R,Rcpp,我一直在学习Dirk Eddelbuettel的Rcpp教程: 我已经学会如何保存一个目录中的C++文件并调用它,并从R中运行它。我运行的C++文件叫做“Logab2.2. CCP”,它的内容直接来自Dirk的幻灯片之一: #include <Rcpp.h> using namespace Rcpp; inline double f(double x) { return ::log(::fabs(x)); } // [[Rcpp::export]] std::vector&l
Rcpp
教程:
<>我已经学会如何保存一个目录中的C++文件并调用它,并从R中运行它。我运行的C++文件叫做“Logab2.2. CCP”,它的内容直接来自Dirk的幻灯片之一:
#include <Rcpp.h>
using namespace Rcpp;
inline double f(double x) { return ::log(::fabs(x)); }
// [[Rcpp::export]]
std::vector<double> logabs2(std::vector<double> x) {
std::transform(x.begin(), x.end(), x.begin(), f);
return x;
}
我在Windows7机器上运行的代码来自默认安装的R GUI。我还安装了最新版本的Rtools
。上面的R代码似乎需要相对较长的时间才能运行。我猜想大部分时间都是用来编译C++代码的,一旦C++代码被编译,它运行得就非常快。code>Microbenchmark显然表明Rcpp
减少了计算时间
<>我以前从未使用过C++,但是我知道当我编译C代码时,我得到了一个*.exe文件。我从名为logabs2.exe的文件中搜索了我的硬盘,但找不到。我想知道上面的C++代码是否可能运行得更快,如果创建了<代码> LogABS2.exe < /C>文件。是否可以创建一个logabs2.exe
文件并将其存储在某个文件夹中,然后让Rcpp随时调用该文件?我不知道这是否有道理。如果我可以在**exe文件中存储C++函数,那么也许每次我想用RCPP使用它时,我就不必编译函数,那么RCPP代码可能会更快。
对不起,如果这个问题没有意义或重复。如果可以将C++函数存储为*.exe文件,我希望有人会告诉我如何修改上面的R代码来运行它。谢谢你在这方面的任何帮助,或者让我明白为什么我的建议不可能或不被推荐
我期待着看德克的新书。你说呢
我以前从来没有使用过C++,但是我知道编译C代码时
我得到一个*.exe文件
如果并且只有您构建了一个可执行文件,这才是真的。在这里,我们构建了可动态加载的库,这些库根据操作系统的不同而具有不同的扩展名:.dll用于Windoze,.so用于Linux,.dynlib用于OS X
所以这里没有错,你只是有一个错误的假设 如果你想得到一些可以保留的实体,你需要的是一个R
包。网上有很多资源可以学习如何制作它们(例如)
我们有Rcpp.package.skeleton
您可能会发现它很有用
因此,在安装包时,函数只需编译一次,然后您就可以使用它了 感谢user1981275、Dirk Eddelbuettel和Romain Francois的回复。下面是我编译C++文件并创建**dll的方法,然后调用并使用*.dll文件在<代码> r>代码> < /p>
第一步。我创建了一个名为“c:\users\mmiller21\myrpackages”的新文件夹,并将文件“logabs2.cpp”粘贴到该新文件夹中。“logabs2.cpp”文件是按照我的原始帖子中的描述创建的
第二步。在新文件夹中,我使用我编写的名为“new package creation.R”的R
文件创建了一个名为“logabs2”的新R
包。“新建包创建.r”的内容包括:
setwd('c:/users/mmiller21/myrpackages/')
library(Rcpp)
Rcpp.package.skeleton("logabs2", example_code = FALSE, cpp_files = c("logabs2.cpp"))
我在Hadley Wickham的一个网站上找到了Rcpp.package.skeleton
的上述语法:
第三步。我使用DOS命令窗口中的以下行在R
中安装了新的R
包“logabs2”:
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
其中:
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命令窗口中使用的语法是通过反复试验发现的,可能并不理想。在某个时候,我在“C:\Program Files\R\R-3.0.1\bin\x64>”中粘贴了一份“logabs2.cpp”,但我认为这并不重要
第四步。安装新的R
软件包后,我使用一个名为“new package usage.R”的R
文件运行它,该文件位于“c:/users/mmiller21/myrpackages/”文件夹中(尽管我认为该文件夹并不重要)。“new package usage.r”的内容包括:
library(logabs2)
logabs2(seq(-5, 5, by=2))
结果是:
# [1] 1.609438 1.098612 0.000000 0.000000 1.098612 1.609438
此文件在我未询问的情况下加载了包Rcpp
在这种情况下,如果我做得正确,baseR
更快
#> 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
虽然在本例中,base R似乎更快或与*.dll文件一样快,但我毫不怀疑,在大多数情况下,将*.dll文件与Rcpp
一起使用将比baseR
更快
这是我第一次尝试创建R包或使用Rcpp,毫无疑问,我没有使用最有效的方法。另外,我为这篇文章中的任何印刷错误道歉
编辑
在下面的评论中,我认为Romain Francois建议我将*.cpp文件修改为以下内容:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector logabs(NumericVector x) {
return log(abs(x));
}
基本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
这可能是因为baseR
已经矢量化了。我怀疑对于更复杂的函数baseR
会慢得多。或者我仍然没有使用最有效的方法,或者我只是在某个地方犯了一个错误。您看过命令R CMD SHLIB
?这样你就可以编译你的C++函数到一个DLL文件,然后用<代码> Dyn。有关详细信息,请查看?SHLIB
和?dyn.load
@user1981275感谢您的评论。到目前为止,我已经做到了这一点:C:\ProgramFiles\R\R-3.0.1\bin\x64>rcmd SHLIB-o C:\users\mmiller21\documents\R\win library\3.0\rcpp\include\logabs2.dll C:\users\mmiller21\documents\R\win library\3.0\rcpp\include\logabs2.cpp我得到了以下消息:make:**无规则生成目标'c:\users\mmiller21\documents\r\win library\3.0\rcpp\include\logabs2.o',n
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)
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