I made a "copy" of a piece of Java code that works in approx. 400 ms ( https://gist.github.com/threecee/cb1c55ad1ce9ac4b1903 ). My version is in F #, which uses Parallel.ForEach, and I also tried using PSeq, but none of the versions were faster than 7 seconds.
It's not that I should have my piece of code faster than the one I copied, but I would really like to know what could be done to improve performance in sample calculations like this in F #.
open System.Threading.Tasks
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 compute all unique products x*y where x: 1->8000 and y: 1-8000.
UPDATE:
Updated code after using Array.initas the jpe proposed in response looks like this:
open System.Threading.Tasks
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)