Why is this piece of code not faster?

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
#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 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
#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)
+4
2

, . ,

let bits = [| for i in 1 .. ((n+1)*(n+1)) -> 0 |]

let bits = Array.init ((n+1)*(n+1)) (fun _ -> 0)

, Java.

: , Array.zeroCreate . , - ,

let bits = Array.zeroCreate ((n+1)*(n+1))

: , , . : - IL newarr, , , .Net . Array.init , "" , zeroCreateUnchecked , .

, : Microsoft.FSharp.Collections.Array, , , Microsoft.FSharp.Primitives.Basics.Array.

+5

All Articles