首页 > 解决方案 > 使用 RCPP 快速更新大列表 (>50M)

问题描述

我对RCPP和很陌生C++

我试图使用我用 C++ 编写的一段代码来快速更新一个巨大的列表(59M 元素),而且我快到了。它有效,速度快了 12k。

编辑:

有没有更快的方法来更新列表的单个元素? (我原来的问题已在评论中解决。)

下面是一个带有小列表的简化示例和一个带有大列表的基准。

输入示例:

set.seed(311)
L <- lapply(1:5, function (x) {rnorm(sample(1:5, size = 1, replace = T))} )

L[[1]] 
[1] 9 7 8 3

输出 R 代码:

new_element <- c(1, 2)
k = 1L
L[[k]] <- c(L[[k]], new_element)

L[[k]]
[1] 9 7 8 3 1 2

功能 RCPP 代码:

#include <Rcpp.h>
using namespace Rcpp;


// [[Rcpp::export]]
List assign_list(List x, int k, NumericVector upd){
  // initialize an accumulator variable

  NumericVector xk = x[k-1];
  NumericVector y = NumericVector(xk.size() + upd.size());

  for(int i = 0; i < xk.size(); ++i) {
    y[i] = xk[i];
  }

  int i = 0;
  for(int j = xk.size(); j < y.length(); ++j) {
    y[j] = upd[i];
    i += 1;
  }

  x[k-1] = y;

  return(y);

}

输出 RCPP 代码

set.seed(311)
L <- lapply(1:5, function (x) {sample(1:10, sample(1:5, size = 1, replace = T))} )

assign_list(L, 1L, new_element)
L[[k]] 
[1] 9 7 8 3 1 2

基准

set.seed(311)
L_big <- lapply(1:10000000, function (x) {sample(1:10, sample(1:5, size = 1, replace = T))} )
microbenchmark(times = 5L,
  "r"   = L_big[[k]] <- c(L_big[[k]], new_element),
  "C++" = assign_list(L_big, k, new_element)
)

Unit: microseconds
 expr   min         lq        mean     median         uq        max neval cld
    r 9.625 199263.953 163516.4662 201014.890 205111.533 212182.330     5   b
  C++ 3.850     14.758     13.4744     15.078     15.399     18.287     5  a 
> 

标签: c++rperformancesubsetrcpp

解决方案


推荐阅读