user1981275、Dirk Eddelbuettel、Romain Francois の回答に感謝します。以下は、C++ ファイルをコンパイルして *.dll を作成し、.dll 内でその *.dll ファイルを呼び出して使用する方法ですR
。
ステップ 1. 「c:\users\mmiller21\myrpackages」という名前の新しいフォルダーを作成し、「logabs2.cpp」ファイルをその新しいフォルダーに貼り付けました。ファイル「logabs2.cpp」は、私の元の投稿で説明したように作成されました。
ステップ 2. 新しいフォルダー内に、作成した「新しいパッケージの作成.r」というファイルをR
使用して、「logabs2」という名前の新しいパッケージを作成しました。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 の Web サイトの 1 つで 上記の構文を見つけました: https://github.com/hadley/devtools/wiki/Rcpp
ステップ 3. DOS コマンド ウィンドウで次の行を使用して、新しいR
パッケージ「logabs2」をインストールしました。R
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 コマンド ウィンドウで使用される構文は、試行錯誤によって発見されたものであり、理想的ではない可能性があります。ある時点で、'logabs2.cpp' のコピーを 'C:\Program Files\R\R-3.0.1\bin\x64>' に貼り付けましたが、それは問題ではないと思います。
ステップ 4. 新しいR
パッケージをインストールした後、「c:/users/mmiller21/myrpackages/」フォルダーにある「new package usage.r」という名前のファイルを使用してR
実行しました (フォルダーは重要ではないと思いますが)。「新しいパッケージの使用法.r」の内容は次のとおりです。
library(logabs2)
logabs2(seq(-5, 5, by=2))
出力は次のとおりです。
# [1] 1.609438 1.098612 0.000000 0.000000 1.098612 1.609438
このファイルは、Rcpp
私に尋ねることなくパッケージをロードしました。
この場合R
、これを正しく行ったと仮定すると、base の方が高速でした。
#> 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
すると base よりも高速になることに疑いの余地はありません。R
これは、R パッケージを作成したり、Rcpp を使用したりする私の最初の試みであり、間違いなく最も効率的な方法を使用していませんでした。また、本文中に誤字脱字がありましたことをお詫び申し上げます。
編集
以下のコメントで、Romain Francois が *.cpp ファイルを次のように変更することを提案したと思います。
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector logabs(NumericVector x) {
return log(abs(x));
}
そして、R
今行ったパッケージを再作成します。R
次に、次のコードを使用してbase と新しいパッケージを比較しました。
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)
ベース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
がはるかに遅くなると思います。あるいは、最も効率的なアプローチをまだ使用していないか、単にどこかでエラーを犯しただけかもしれません。