这不是一个答案,但我想我会发布一些测试结果,希望其他人会知道发生了什么:
> data <- matrix(rnorm(1000 * 10000), nrow=10000)
> system.time(foreach(j=1:1000, .combine = function(...) NULL, .multicombine=TRUE) %do% { sum(data[,j]) })
utilisateur système écoulé
0.643 0.031 0.674
> system.time(foreach(j=1:1000, .combine = function(...) NULL, .multicombine=TRUE) %dopar% { sum(data[,j]) })
utilisateur système écoulé
0.613 0.215 0.653
> system.time(foreach(j=1:1000) %dopar% { sum(data[,j]) })
utilisateur système écoulé
0.537 0.122 0.745
> system.time(foreach(j=1:1000) %do% { sum(data[,j]) })
utilisateur système écoulé
0.650 0.028 0.681
> system.time (for (j in 1:1000) { sum(data[,j]) })
utilisateur système écoulé
0.153 0.069 0.222
简而言之,使用内置的for 仍然比串行的foreach 快得多。使用dopar 并不能真正取胜,而且将所有东西放在一起似乎并不是一直需要花费的时间(可能仍然是将数据传输回主控需要很长时间)。您还可以争辩说,由于计算如此简单,开销自然会占主导地位。所以让我们做一些更复杂的事情:
> data <- matrix(rnorm(3000 * 10000), nrow=10000)
> system.time (for(j in 1:6000) { sum(lgamma(exp(data[,(j - 1) %% 3000 + 1]))) })
utilisateur système écoulé
11.215 1.272 12.490
> system.time (foreach(j=1:6000, .combine=c) %do% { sum(lgamma(exp(data[,(j - 1) %% 3000 + 1]))) })
utilisateur système écoulé
14.304 0.468 15.788
> system.time (foreach(j=1:6000, .combine=c) %dopar% { sum(lgamma(exp(data[,(j - 1) %% 3000 + 1]))) })
utilisateur système écoulé
14.377 11.839 10.358
现在dopar 开始胜出,但三者仍然具有相当的可比性,并且内置的for 并不是那么糟糕,即使有所有额外的工作。但是通信开销呢?我们只返回转换后的数据(每次迭代 10,000 个数字),而不是求和。
> system.time (for(j in 1:6000) { lgamma(exp(data[,(j - 1) %% 3000 + 1])) })
utilisateur système écoulé
11.092 1.189 12.302
> system.time (foreach(j=1:6000, .combine=function (...) NULL, .multicombine=TRUE) %do% { lgamma(exp(data[,(j - 1) %% 3000 + 1])) })
utilisateur système écoulé
14.902 1.867 22.901
> system.time (foreach(j=1:6000, .combine=function (...) NULL, .multicombine=TRUE) %dopar% { lgamma(exp(data[,(j - 1) %% 3000 + 1])) })
^C
Timing stopped at: 2.155 0.706 241.948
>
在这里,不必费心保留结果的for 循环大约需要和以前一样长的时间。这次%do% 版本花了更长的时间。而%dopar% 可能正在通过共享内存传输结果?我决定在大约 4 分钟后杀死它。