Bardziej wydajne jest tworzenie połączenia z bazą danych raz na pracownika, a nie raz na zadanie. Niestety mclapply nie zapewnia mechanizmu inicjowania pracowników przed wykonaniem zadań, więc nie jest to łatwe przy użyciu zaplecza doMC, ale jeśli używasz zaplecza doParallel, możesz zainicjować pracowników za pomocą clusterEvalQ. Oto przykład, jak zmienić strukturę kodu:
library(doParallel)
cl <- makePSOCKcluster(detectCores())
registerDoParallel(cl)
clusterEvalQ(cl, {
library(DBI)
library(RPostgreSQL)
drv <- dbDriver("PostgreSQL")
con <- dbConnect(drv, dbname="nsdq")
NULL
})
id.qed.foreach <- foreach(i=1588:3638, .inorder=FALSE,
.noexport="con",
.packages=c("DBI", "RPostgreSQL")) %dopar% {
lst <- eval(expr.01) #contains the SQL query which depends on 'i'
qry <- dbSendQuery(con, lst)
tmp <- fetch(qry, n=-1)
dt <- dates.qed2[i]
list(date=dt, idreuters=tmp$idreuters)
}
clusterEvalQ(cl, {
dbDisconnect(con)
})
Ponieważ doParallel i clusterEvalQ używają tego samego obiektu klastra cl
, pętla foreach będzie miała dostęp do obiektu połączenia z bazą danych con
podczas wykonywania zadań.