我已經制作了一個運行在大約20%的Java代碼片的「副本」。 400毫秒(https://gist.github.com/threecee/cb1c55ad1ce9ac4b1903)。我的F#版本使用Parallel.ForEach
,我也嘗試過使用PSeq
,但沒有一個版本比7秒更快。爲什麼這段代碼不是更快?
這並不是說我必須比我複製的代碼更快,但我真的很想知道在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)
代碼的作用是計算所有獨特的產品x*y where x: 1->8000 and y: 1-8000
。
UPDATE: 使用Array.init
作爲JPE在回答中表情說明後,更新的代碼很喜歡這樣的:
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)
只要使用'Parallel.ForEach'不會自動暗示更好的性能......由於線程/任務初始化會導致性能降低,這可能比循環內的實際操作花費的時間更長。 – Matze 2014-12-06 19:00:14
@Matze,你有什麼建議來改善它?我認爲應該有可能接近鏈接到java代碼的性能。 – 2014-12-06 19:03:16