I've made a "copy" of a piece of java code that runs in approx. 400 ms (https://gist.github.com/threecee/cb1c55ad1ce9ac4b1903). My version in F# that uses Parallel.ForEach
and I have also tried with PSeq
but none of the versions is faster than 7 seconds.
It's not that I must have my piece of code faster than the one I copied but I would really like to know what could have been done to improve the performance in a sample calculations like this in F#.
open System.Threading.Tasks
#time
let calculateProducts n =
let bits = [| for i in 1 .. ((n+1)*(n+1)) -> 0 |]
let inner i =
[|i..n|] |> Array.map (fun j -> bits.[j*i] <- 1) |> ignore
Parallel.ForEach([|1 .. n|], (fun i -> inner i)) |> ignore
bits |> Array.sum
printfn "%i" (calculateProducts 8000)
What the code does is calculating all the unique products x*y where x: 1->8000 and y: 1-8000
.
UPDATE:
The updated code after using Array.init
as jpe suggested in an answer look likes this:
open System.Threading.Tasks
#time
let calculateProducts n =
let bits = Array.init ((n+1)*(n+1)) (fun _ -> 0)
let inner i =
let arr = Array.init (n-i+1) (fun x -> x+i)
Parallel.ForEach(arr, (fun j -> bits.[j*i] <- 1)) |> ignore
let arr = Array.init n (fun x -> (x+1))
Parallel.ForEach(arr, (fun i -> inner i)) |> ignore
bits |> Array.sum
printfn "%i" (calculateProducts 8000)