C++ 我应该更喜欢Rcpp::NumericVector而不是std::vector吗?
有什么理由让我更喜欢C++ 我应该更喜欢Rcpp::NumericVector而不是std::vector吗?,c++,rcpp,C++,Rcpp,有什么理由让我更喜欢Rcpp::NumericVector而不是std::vector 例如,下面的两个函数 // [[Rcpp::export]] Rcpp::NumericVector foo(const Rcpp::NumericVector& x) { Rcpp::NumericVector tmp(x.length()); for (int i = 0; i < x.length(); i++) tmp[i] = x[i] + 1.0; return
Rcpp::NumericVector
而不是std::vector
例如,下面的两个函数
// [[Rcpp::export]]
Rcpp::NumericVector foo(const Rcpp::NumericVector& x) {
Rcpp::NumericVector tmp(x.length());
for (int i = 0; i < x.length(); i++)
tmp[i] = x[i] + 1.0;
return tmp;
}
// [[Rcpp::export]]
std::vector<double> bar(const std::vector<double>& x) {
std::vector<double> tmp(x.size());
for (int i = 0; i < x.size(); i++)
tmp[i] = x[i] + 1.0;
return tmp;
}
/[[Rcpp::export]]
Rcpp::NumericVector foo(常量Rcpp::NumericVector&x){
Rcpp::数值向量tmp(x.length());
对于(int i=0;i
当考虑到他们的工作和基准绩效时,他们是同等的。我知道Rcpp提供了sugar和向量化操作,但如果它只是把R的向量作为输入,把返回的向量作为输出,那么我使用哪一个会有什么区别呢?在与R交互时,使用std::vector是否会导致任何可能的问题?“如果不确定,请计时。”
只需将以下几行添加到您已有的文件中:
/*** R
library(microbenchmark)
x <- 1.0* 1:1e7 # make sure it is numeric
microbenchmark(foo(x), bar(x), times=100L)
*/
您的bar()
解决方案需要创建一个副本,以便在R内存池中创建一个R对象<代码>foo()没有。这对于运行多次的大型向量很重要。在这里,我们看到接近的比率约为1.8
在实践中,您是否喜欢一种编码样式而不是另一种编码样式可能并不重要
当考虑到他们的工作和基准绩效时,他们是同等的
SEXP
到std::vector
需要从一个数据结构到另一个数据结构的深度拷贝。(当我输入这个时,@DirkEddelbuettel运行了一个微基准。)const Rcpp::NumericVector&x
)只是一种视觉上的糖分。默认情况下,给定的对象是指针,因此很容易产生涟漪修改效果(见下文)。因此,与有效地“锁定”和“传递引用”的const std::vector&x不存在真正的匹配
std::vector是否会导致任何可能的问题
简言之,没有。支付的唯一惩罚是对象之间的转移
这种转换的好处是,修改分配给另一个NumericVector
的NumericVector
的值不会导致domino更新。本质上,每个std::vector
都是另一个的直接副本。因此,以下情况不可能发生:
#include<Rcpp.h>
// [[Rcpp::export]]
void test_copy(){
NumericVector A = NumericVector::create(1, 2, 3);
NumericVector B = A;
Rcout << "Before: " << std::endl << "A: " << A << std::endl << "B: " << B << std::endl;
A[1] = 5; // 2 -> 5
Rcout << "After: " << std::endl << "A: " << A << std::endl << "B: " << B << std::endl;
}
有什么理由让我更喜欢Rcpp::NumericVector
而不是std::vector
有几个原因:
以前的提示,使用<代码> RCPP::MigialVector >避免了C++()的深度复制。
您可以访问sugar函数
C++中“标记”RCPP对象的能力(例如通过<代码>添加属性>
我不会说这纯粹是基于意见。这个问题确实(无意中)引起了一些担忧。回答得好。应该提到@dcdillon也为std::vector
提供了糖。
#include<Rcpp.h>
// [[Rcpp::export]]
void test_copy(){
NumericVector A = NumericVector::create(1, 2, 3);
NumericVector B = A;
Rcout << "Before: " << std::endl << "A: " << A << std::endl << "B: " << B << std::endl;
A[1] = 5; // 2 -> 5
Rcout << "After: " << std::endl << "A: " << A << std::endl << "B: " << B << std::endl;
}
test_copy()
# Before:
# A: 1 2 3
# B: 1 2 3
# After:
# A: 1 5 3
# B: 1 5 3