當使用R做計算,常常以五萬次為單位的時候,就會開始有點不耐煩,在思考如何提高自己代碼的速度,通常這種計算都會“慢”在某個loop中,通常就是做個t.test或是wilcoxon.test之類的。此時就可以考慮把代碼稍微修改,加入並行(parellel)的概念於其中,這時候可以參考使用foreach這個apckage,(在計算量小的時候,就不用牛刀小試,反而會變慢,因為一開始程序會先分推等等並行前的處置,且最後你還會需要寫代碼把資料合起來成自己想要的格式,通常都是把list變成一個data.frame)。
當然傳統基本的apply, lapply, sapply, eapply, mapply, rapply等都可以用來將這類的任務解決,但本質上這些函數依舊是單核單線程在運算的,而這邊介紹的foreach package則可以支援多核以及在叢集電腦上的多node計算。
在foreach裡面的函數,多為binary operator的形式,最簡單的使用方式,是直接將其替代原本的loop寫法:
#最基本的用法就如同for loop x <- foreach ( i = 1:3) %do% sqrt(i)</div> #其支援多個variable同時來迭代 x <- foreach(a = 1:3, b=rep(10, 3)) %do% ( a + b ) #可以使用curly brace, 裡頭可以包更複雜的運算 x <- foreach(a= 1:3, b= rep(10 ,3)) %do% {</div> a + b }
#使用.combine 選項,可以將運算的複雜度提高 x <- foreach(i = 1:3, .combine=‘c’) %do% exp(i) x <- foreach( i = 1:3, .combine=‘cbind’) %do% rnorm(4)</div> #cfun為使用自訂函數 x <- foreach( i = 1:3, .combine=‘cfun’, .multicombine=TRUE) %do% rnorm(4)
基本上使用%do%可以在loop上更多元的操作,而foreach最強大的其實是他並行的運算指令,其實就把%do%改成%dopar%就可以了,不過其實foreach本身是有一些缺欠的,比如他內部跟操作系統中線程的處理,是使用fork而非exec,所以在並行中在指令中間暫時性的variable時,就會出現一些問題,這部分會有另一個package來幫其補齊不足(doParellel package)
PS:當combine pipe使用時,有可能會造成ram需求大升,造成問題!