Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/164.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我应该更喜欢Rcpp::NumericVector而不是std::vector吗?_C++_Rcpp - Fatal编程技术网

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运行了一个微基准。)
  • Rcpp对象的标记(例如,
    const Rcpp::NumericVector&x
    )只是一种视觉上的糖分。默认情况下,给定的对象是指针,因此很容易产生涟漪修改效果(见下文)。因此,与有效地“锁定”和“传递引用”的
    const std::vector&x不存在真正的匹配
  • 在与R交互时,使用
    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