在哪些情况下用 C++ 编写部分 R 代码或将其并行化(在 R 或 Rcpp 中)最有效?

In which cases is it most efficent to write a part of R code in C++ or parallelise it (in R or Rcpp)?

我有一些具有特殊结构的数据,需要我编写自己的 k-means 函数。不远,我已经注意到在计算中心到所有数据点的距离时计算时间非常长。因为我的数据将来会大 60 倍左右,而且我需要运行许多不同的集群大小,所以我非常关心速度。

我附上了一个计算从一个随机采样中心到每个数据点的距离的最小示例。我还没有在 R 中使用 C++ 或并行计算的经验,但我最不确定这些解决方案中的哪一个是解决我的问题的最佳方法(这里和那里有些人声称你应该在任何时候并行化,有些人声称它几乎从来没有必要,一些建议,一些反对使用 Rcpp 的建议)。与生活中的大多数事情一样,我确信在某些情况下所有这些答案都是正确的。但是,一般情况下什么时候采用哪种方法?

(我已经对这段代码进行了概要分析,但在 R 代码中找不到任何可以提高速度的地方。但是,如果您有任何建议,也请告诉我!)

x <- matrix(runif(15000*34),nrow = 15000, ncol = 34)
w <- matrix(runif(15000*17),nrow = 15000, ncol = 17)
k <- 3
i <- 1
centers <- x[sample.int(nrow(x), size = k),]

weighted_matching <- function(point,center,weight){
    point <- matrix(point, ncol = 2, nrow = 17, byrow = T)
    center <- matrix(center, ncol = 2, nrow = 17, byrow = T)
    1/sum(weight) * sum(weight * apply(point, 1, function(x,y) sqrt(sum((x-y)^2)), y = center))
}

system.time(
    apply(x, 1, weighted_matching, weight = w, center = centers[i,])
)

有两种情况我用C++代替R:

  • 遍历大量元素(大型 for 循环)
  • 想要减少内存占用

在您的情况下,您已经在使用矢量化代码而不是循环,因此第一点不适用。

然而,第二点可能是有益的;实际上,您正在计算 (x-y)^2,这会创建两个新的临时向量。 用 C++ 重写它以使用更少的内存并可能在计算时间上获得 2-3 倍的改进是有益的。

但是,当我通常听说 "computing distances" 时,我可能会尝试使用矩阵计算(线性代数)来推导它。