为什么LogicalVector到std :: vector <double>转换需要这么长时间?

时间:2015-12-12 23:59:55

标签: r rcpp rcpp11

当使用Rcpp与外部库接口时,我们必须转换 Rcpp内置容器类,最常见的是标准容器 类。这种转换一如既往需要成本。通常这种开销 是相当确定的,但在Rcpp转换getName()的情况下 到LogicalVector成本似乎与另一种类型不符 铸造/促销费用......

考虑以下六个简单转换的相等性 LogicalVector到std :: vector containers ...

std::vector<double>

由于Rcpp的模板魔法,我们得到了这种平等。我的模板fu不是 足够强大,可以深入研究为什么开销有这么大的差异 如这些基准测试所示,手动转换与自动转换相比 结果...

// Equality check functions.
// [[Rcpp::export]]
svi test_auto_conversion_std_int(const svi& v) {
  return v;
}
// [[Rcpp::export]]
svi test_as_conversion_std_int(const lv& v) {
  svi v2 = as<svi>(v);
  return v2;
}
// [[Rcpp::export]]
svi test_manual_conversion_std_int(const nv& v) {
  svi v2(v.begin(),v.end());
  return v2;
}
// [[Rcpp::export]]
svd test_auto_conversion_std_dbl(const svd& v) {
  return v;
}
// [[Rcpp::export]]
svd test_as_conversion_std_dbl(const lv& v) {
  svd v2 = as<svd>(v);
  return v2;
}
// [[Rcpp::export]]
svd test_manual_conversion_std_dbl(const nv& v) {
  svd v2(v.begin(),v.end());
  return v2;
}

    > small_l_vec <- c(T,F,NA)
    > small_i_vec <- as.integer(small_l_vec)
    > small_n_vec <- as.numeric(small_l_vec)
    > all( identical(small_i_vec, test_auto_conversion_std_int(small_l_vec)),
    +      identical(small_i_vec, test_as_conversion_std_int(small_l_vec)),
    +    .... [TRUNCATED] 
    [1] TRUE

    > all( identical(small_n_vec, test_auto_conversion_std_dbl(small_l_vec)),
    +      identical(small_n_vec, test_as_conversion_std_dbl(small_l_vec)),
    +    .... [TRUNCATED] 
    [1] TRUE

直接比较使用Rcpp容器的成本,自动转换 to std类似容器的容器,以及类似促销类型的容器......

    > benchmark_as_tested_for_equality()  # includes copy costs
    Unit: microseconds
                                      expr   median neval
         test_as_conversion_std_int(l_vec) 10121.17   500
     test_manual_conversion_std_int(l_vec) 12545.34   500
       test_auto_conversion_std_int(l_vec) 12654.28   500
     test_manual_conversion_std_dbl(l_vec) 18590.10   500
         test_as_conversion_std_dbl(l_vec) 19653.39   500
       test_auto_conversion_std_dbl(l_vec) 26897.93   500  <<< OUCH!

......很容易看到异常值。如果我们尝试将逻辑向量作为类似的std容器传递然后让 c ++在构建新容器时进行促销,结果不是更好......

# Functions return "size" only so no copy costs.

> declared_direct()      > declared_std_like_types()
          expr median               expr   median
rcpp_lv(l_vec) 1.1280    std_bool(l_vec) 7352.500


> declared_promoted_r()  > declared_promoted_std()
          expr   median            expr     median
rcpp_iv(l_vec) 2932.712  std_int(l_vec)   6790.508
rcpp_nv(l_vec) 5359.769  std_dbl(l_vec)  12810.550 <<< OUCH!

如果 > declared_std_like_types_promoted_using_std_promotion() expr median std_bool_promote_int(l_vec) 12725.724 std_bool_promote_dbl(l_vec) 13626.782 由Rcpp推广且 用于填充 一个标准的容器直接结果好多了。

LogicalVector

我无法弄清楚为什么自动转换 > declared_promoted_r_to_std_like_type() expr median rcpp_lv_promote_std_int(l_vec) 5019.586 rcpp_lv_promote_std_dbl(l_vec) 8007.522 <<< Much better! LogicalVector的速度相对较慢......

0 个答案:

没有答案