当前位置:  开发笔记 > 编程语言 > 正文

我应该更喜欢Rcpp :: NumericVector而不是std :: vector吗?

如何解决《我应该更喜欢Rcpp::NumericVector而不是std::vector吗?》经验,为你挑选了2个好方法。

是否有任何理由为什么我应该更喜欢Rcpp::NumericVectorstd::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 bar(const std::vector& x) {
  std::vector tmp(x.size());
  for (int i = 0; i < x.size(); i++)
    tmp[i] = x[i] + 1.0;
  return tmp;
}

在考虑其工作和基准性能时是等效的.我知道Rcpp提供了糖和矢量化操作,但是如果只是将R的向量作为输入并将向量作为输出返回,那么我使用哪一个会有什么区别吗?std::vector在与R交互时可以使用导致任何可能的问题吗?



1> coatless..:

在考虑其工作和基准性能时是等效的.

    我怀疑基准测试是否准确,因为从a SEXPstd::vector需要从一个数据结构到另一个数据结构的深层复制.(当我打字时,@ DirkEddelbuettel运行了一个微基准测试.)

    Rcpp对象的标记(例如const Rcpp::NumericVector& x)只是视觉糖.默认情况下,给定的对象是指针,因此很容易产生波纹修改效果(见下文).因此,没有与const std::vector& x有效"锁定"和"传递引用" 存在的真实匹配.

std::vector在与R交互时可以使用导致任何可能的问题吗?

简而言之,没有.支付的唯一惩罚是对象之间的转移.

这种转移的好处是修改NumericVector分配给另一个转移的值NumericVector不会导致多米诺骨牌更新.实质上,每个std::vector都是另一个的直接副本.因此,以下情况不可能发生:

#include

// [[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

是否有任何理由为什么我应该更喜欢Rcpp::NumericVectorstd::vector

有几个原因:

    如前所述,使用Rcpp::NumericVector避免了C++深层复制. std::vector

    您可以访问功能.

    能够在C++中 "标记" Rcpp对象(例如,通过添加属性).attr()


好答案。应该提到@dcdillon的[RcppHoney](https://github.com/dcdillon/RcppHoney)也为`std :: vector <>`提供了糖。

2> Dirk Eddelbu..:

"如果不确定,只需要时间."

只需将这几行添加到您已有的文件中:

/*** R
library(microbenchmark)
x <- 1.0* 1:1e7   # make sure it is numeric
microbenchmark(foo(x), bar(x), times=100L)
*/

然后只是调用sourceCpp("...yourfile...")生成以下结果(加上有符号/无符号比较的警告):

R> library(microbenchmark)

R> x <- 1.0* 1:1e7   # make sure it is numeric

R> microbenchmark(foo(x), bar(x), times=100L)
Unit: milliseconds
   expr     min      lq    mean  median      uq      max neval cld
 foo(x) 31.6496 31.7396 32.3967 31.7806 31.9186  54.3499   100  a 
 bar(x) 50.9229 51.0602 53.5471 51.1811 51.5200 147.4450   100   b
R> 

您的bar()解决方案需要制作副本以在R内存池中创建R对象.foo()才不是.这对于你经常运行多次的大型向量很重要.在这里,我们看到收盘率约为1.8.

在实践中,如果您喜欢一种编码风格而不是另一种编码风格,则可能无关紧要.

推荐阅读
雯颜哥_135
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有