Non penso che una lista sia il giusto tipo di dati per questo. Perché è solo una lista collegata, i dati saranno necessariamente utilizzati in sequenza. Sebbene sia possibile valutare gli articoli in parallelo, non si otterrà molto nel passaggio di riduzione. Se si ha realmente bisogno di un elenco, penso che la funzione migliore sarebbe solo
parFold f = foldl1' f . withStrategy (parList rseq)
o forse
parFold f = foldl1' f . withStrategy (parBuffer 5 rseq)
Se la fase di riduzione è complesso, si potrebbe ottenere un guadagno suddividendo la lista come questa:
parReduce f = foldl' f mempty . reducedList . chunkList . withStrategy (parList rseq)
where
chunkList list = let (l,ls) = splitAt 1000 list in l : chunkList ls
reducedList = parMap rseq (foldl' f mempty)
mi sono preso la libertà di assumere i dati è un Monoid
per mempty, se questo non è possibile è possibile sostituire mempty con il proprio tipo di vuoto, o l'uso caso peggiore foldl1'
.
Ci sono due operatori da Control.Parallel.Strategies
in uso qui. Lo parList
valuta tutti gli elementi della lista in parallelo. Dopodiché, lo chunkList
divide l'elenco in blocchi di 1000 elementi. Ciascuno di questi blocchi viene quindi ridotto in parallelo dal numero parMap
.
Si potrebbe anche provare
parReduce2 f = foldl' f mempty . reducedList . chunkList
where
chunkList list = let (l,ls) = splitAt 1000 list in l : chunkList ls
reducedList = parMap rseq (foldl' f mempty)
A seconda esattamente come è distribuito il lavoro, uno di questi può essere più efficiente rispetto agli altri.
Se è possibile utilizzare una struttura dati con un buon supporto per l'indicizzazione (Array, Vector, Mappa, ecc.), È possibile eseguire suddivisioni binarie per il passaggio di riduzione, che sarà probabilmente nel complesso migliore.
Come si è notato, l'elenco è una struttura di dati scadente per la suddivisione parallela ricorsiva. Vuoi una sorta di struttura ad albero binario/corda come nella lingua della Fortezza: http://labs.oracle.com/projects/plrg/Publications/ICFPAugust2009Steele.pdf – sclv