函数内部的并行R代码比函数外部的慢

函数内部的并行R代码比函数外部的慢,r,performance,parallel-processing,R,Performance,Parallel Processing,我有一些并行的R代码,我想放在一个函数内,但是当代码在函数内而不是函数外运行时,它的运行速度要慢得多 代码获取坐标矩阵并将其转换为sf对象。下面的演示代码运行相同的过程2次 简单代码 相同的代码,但在一个功能内 示例代码: # Packages library(parallel) library(sf) library(pbapply) # Sample Data mat = matrix(runif(1e6,max = 1e5), ncol = 2) seqs = 1:(nrow(mat

我有一些并行的R代码,我想放在一个函数内,但是当代码在函数内而不是函数外运行时,它的运行速度要慢得多

代码获取坐标矩阵并将其转换为
sf
对象。下面的演示代码运行相同的过程2次

  • 简单代码
  • 相同的代码,但在一个功能内
示例代码:

# Packages
library(parallel)
library(sf)
library(pbapply)

# Sample Data
mat = matrix(runif(1e6,max = 1e5), ncol = 2)
seqs = 1:(nrow(mat)-1)
ncores = 6 # Change as needed

start1 = Sys.time()
# Code not running in a function #########
cl = parallel::makeCluster(ncores)
parallel::clusterExport(cl=cl, varlist=c("mat"), envir = environment())
geoms = pbapply::pblapply(seqs, function(y){sf::st_linestring(mat[c(y,y+1),c(1,2)])}, cl = cl)
parallel::stopCluster(cl)

end1 = Sys.time()

# Same code in a function ###########
func = function(mat, seqs, ncores){
  cl = parallel::makeCluster(ncores)
  parallel::clusterExport(cl=cl, varlist=c("mat"), envir = environment())
  geoms = pbapply::pblapply(seqs, function(y){sf::st_linestring(mat[c(y,y+1),c(1,2)])}, cl = cl)
  parallel::stopCluster(cl)
  return(geoms)
}

start2 = Sys.time()
res = func(mat, seqs, ncores)
end2 = Sys.time()


# Compare Results 
difftime(end1, start1, units = "s")
difftime(end2, start2, units = "s")
当比较时间时,函数中的代码会显著减速

difftime(end1, start1, units = "s")
Time difference of 41.98823 secs
difftime(end2, start2, units = "s")
Time difference of 114.983 secs

如果您的问题是延迟的原因,那么原因很可能是因为R制作了矩阵的副本并将副本传递给函数。在一百万个元素中,这是一个需要复制的相当大的对象。处理内存不是R的强项,这就是为什么在循环中增长对象是一种非常糟糕的做法。这是有道理的,但不仅仅如此,如果你运行代码,你会看到
geoms=pbapply::pblapply(seqs,function(y){sf::st_linestring(mat[c(y,y+1),c(1,2)],cl=cl)
line是运行缓慢的那一行,根据该行代码,复制应该已经发生