我有一个相当大的对象列表,我想并行应用一个复杂的函数,但我当前的方法使用了太多内存。我认为参考类可能会有所帮助,但是使用mcapply
修改它们似乎不起作用。
该函数修改对象本身,因此我用新对象覆盖原始对象。由于该对象是一个列表,而我只修改了其中的一小部分,因此我希望 R 的修改时复制语义能够避免制作多个副本;然而,在运行它时,我正在做的事情似乎并非如此。这是我一直在使用的基本 R 方法的一个小示例。它正确地将余额重置为零。
## make a list of accounts, each with a balance
## and a function to reset the balance
foo <- lapply(1:5, function(x) list(balance=x))
reset1 <- function(x) {x$balance <- 0; x}
foo[[4]]$balance
## 4 ## BEFORE reset
foo <- mclapply(foo, reset1)
foo[[4]]$balance
## 0 ## AFTER reset
似乎使用引用类可能会有所帮助,因为它们是可变的,并且在使用时lapply
它确实如我所料;余额重置为零。
Account <- setRefClass("Account", fields=list(balance="numeric"),
methods=list(reset=function() {balance <<- 0}))
foo <- lapply(1:5, function(x) Account$new(balance=x))
foo[[4]]$balance
## 4
invisible(lapply(foo, function(x) x$reset()))
foo[[4]]$balance
## 0
但是当我使用mclapply
,它无法正确重置。请注意,如果您使用的是 Windows 或mc.cores=1
, lapply
将会被调用。
foo <- lapply(1:5, function(x) Account$new(balance=x))
foo[[4]]$balance
## 4
invisible(mclapply(foo, function(x) x$reset()))
foo[[4]]$balance
## 4
这是怎么回事?如何并行使用参考类?有没有更好的方法来避免不必要的对象复制?