Какой из списка, массива или последовательности более эффективен для параллельной обработки и может легко реализовать параллельные операции, такие как parmap
, parfilter
и т. д.?
РЕДАКТИРОВАТЬ:
Спасибо за предложения. Array.Parallel
выглядит хорошим вариантом. Также проверил PSeq.fs
, и у меня возник вопрос о том, как работает pmap
ниже.
let pmap f xs =
seq { for x in xs -> async { return f xs } }
|> Async.Parallel
|> Async.RunSynchronously
Создается ли новый поток для каждого элемента в последовательности? Если да, то есть ли способ разбить последовательность на фрагменты и создать новую задачу для каждого фрагмента для параллельной оценки?
Я также хотел бы узнать, существует ли аналогичная реализация pmap
для списка. Я нашел у Томаса реализацию ParallelList
в своем блоге здесь. Но я не уверен, не требует ли преобразование списка в массив для выполнения параллельных вычислений слишком больших накладных расходов и можно ли этого избежать?
РЕДАКТИРОВАТЬ: Спасибо за ваш вклад. Томас ответил на мой первоначальный вопрос.
Отвечая на мой собственный вопрос в первом редактировании:
Я попытался разбить большой список на куски, а затем применить асинхронность к каждому подсписку.
let pmapchunk f xs =
let chunks = chunk chunksize xs
seq { for chunk in chunks -> async { return (Seq.map f) chunk } }
|> Async.Parallel
|> Async.RunSynchronously
|> Seq.concat
Результаты: map
: 15 с, pmap
: 7 с, pmapchunk
: 10 с.