I\'m playing around with parallellization in R for the first time. As a first toy example, I tried
library(doMC)
registerDoMC()
B<-10000
myFunc<-func
for
will run sqrt
B times, presumably discarding the answer each time. foreach
, however, returns a list containing the result of each execution of the loop body. This would contribute considerable extra overhead, regardless of whether it's running in parallel or sequential mode (%dopar%
or %do%
).
I based my answer by running the following code, which appears to be confirmed by the foreach vignette, which states "foreach differs from a for loop in that its return is a list of values, whereas a for loop has no value and uses side effects to convey its result."
> print(for(i in 1:10) sqrt(i))
NULL
> print(foreach(i = 1:10) %do% sqrt(i))
[[1]]
[1] 1
[[2]]
[1] 1.414214
[[3]]
... etc
UPDATE: I see from your updated question that the above answer isn't nearly sufficient to account for the performance difference. So I looked at the source code for foreach
and can see that there is a LOT going on! I haven't tried to understand exactly how it works, however do.R
and foreach.R
show that even when %do%
is run, large parts of the foreach
configuration is still run, which would make sense if perhaps the %do%
option is largely provided to allow you to test foreach
code without having to have a parallel backend configured and loaded. It also needs to support the more advanced nesting and iteration facilities that foreach
provides.
There are references in the code to results caching, error checking, debugging and the creation of local environment variables for the arguments of each iteration (see the function doSEQ
in do.R
for example). I'd imagine this is what creates the difference that you've observed. Of course, if you were running much more complicated code inside your loop (that would actually benefit from a parallelisation framework like foreach
), this overhead would become irrelevant compared with the benefits it provides.