Does F# Async.Parallel speed up calculations?

f#, parallel-processing

Solution

Using F# `async` for purely CPU-bound tasks works only if the tasks perform some more complicated operation. If you're trying to parallelize code that does something very simple, then it is better to use PLINQ (and the Task Parallel Library), which are more optimized for these kind of problems.

However, even then, getting speedup in a trivial case as the one you have is difficult. If you want to experiment with this a bit more, you can try this:

// Turn on timing in F# interactive
#time 
let data = [| 1 .. 5000000*3 |]

// Use standard 'map' function for arrays
let result = Array.map (fun x -> (x * x) / 75) data 
// Use optimized parallel version
let result = Array.Parallel.map (fun x -> (x * x) / 75) data

Note that using `Array.map` itself is a lot faster than using sequence expressions and then converting the result to an array. If you want to use more complex operations than mapping, then F# PowerPack contains `PSeq` module with functions similar to those in `Seq` or `List`:

#r @"FSharp.PowerPack.Parallel.Seq.dll"

data 
|> PSeq.map (fun a -> ...)
|> PSeq.filter (fun a -> ...)
|> PSeq.sort
|> Array.ofSeq

If you want to read more about this, I wrote a blog series about parallel programming in F# recently.

Problem

Does the "Async.Parallel" construction really help to make calculations faster on a multi-core system? Are .NET TPL "Tasks" involved here somehow? ``` open System; let key = Console.ReadKey(true); let start = System.DateTime.Now let pmap f l = seq { for a in l do yield async {return f a} } |> Async.Parallel |> Async.RunSynchronously let map f l = seq {for a in l do yield f a} let work f l = match key.KeyChar with | '1' -> pmap f l | '2' -> Seq.toArray (map f l) | _ -> [||] let result = work (fun x -> (x * x) / 75) (seq { 1 .. 100000*3}) let endtime = DateTime.Now - start printfn "%A"endtime; let pause = Console.ReadKey(true); ``` I suppose some of you will explain it theoretically, but I would also appreciate some real world tests.

Original source