Question

F#

[|for index in 1 .. items.Count()-1 -> (* create object here - complex operations *)|]

C#

Object[] newItemArray= new Object[items.Count];

Parallel.For(0, items.Count, index=>
{
    /*complex stuff here*/
    newItemArray[index] = new Object();
});

I have the above C# and F# doing the same thing. Without the Parallel.For the F# is slightly faster. With the Parallel.For the C# takes half as long to execute. How do I properly parallelize the F# to get the same performance boost as the C#?

The way I've tried so far was Array.Parallel.Iteri, so I could use the same index into an array trick I used in C#, but it slowed it down instead of speeding it up.

Edit:

More details on what I'm doing:

I have an enumerable of byte array array array. I have another byte array array array to which I'm comparing the others. I'm sorting the enumerable on % similarity and returning the first 500.

In both the F# and the C# I'm doing a simple nested for loop which increments a counter. When done looping over a particular item in my enumerable, I create a tuple of (item, counter). Once done creating my new enumerable of (item, counter), I sort it on the counter variable, grab the first 500 and then convert back to just an enumerable of item.

The part which I'm putting inside the Parallel.For is the creation of the IEnumerable<Tuple<item, int>>

Was it helpful?

Solution 2

You shouldn't use array comprehension in this case. It's a bit slower than high-order functions and can't be parallelized.

Though I would prefer @ildjarn's solution, here is an equivalent solution to your C# one:

// You need an uninitialized array to fill in later
let newItemArray = Array.zeroCreate items.Count

// Fill in the array in a parallel manner
Array.Parallel.iteri (fun i v ->
    (* create object here - complex operations *)) newItemArray

You can also use Parallel.For directly:

let newItemArray = Array.zeroCreate items.Count 

Parallel.For(0, items.Count, 
             (fun index ->
                 (* complex stuff here *)
                 newItemArray.[index] <- Object())
) |> ignore

It's more verbose but gives you more control over degree of parallelism.

OTHER TIPS

Array.Parallel.init items.Count (fun index ->
    (* create object here - complex operations *))

Official documentation: Parallel.init<'T> Function (F#)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top