нормально, поэтому я выполняю задачу ProjectEuler №14, и я возился с оптимизациями, чтобы чувствовать f # out.F #: Скажите мне, что мне не хватает в использовании Async.Parallel
в следующем коде:
let evenrule n = n/2L
let oddrule n = 3L * n + 1L
let applyRule n =
if n % 2L = 0L then evenrule n
else oddrule n
let runRules n =
let rec loop a final =
if a = 1L then final
else loop (applyRule a) (final + 1L)
n, loop (int64 n) 1L
let testlist = seq {for i in 3 .. 2 .. 1000000 do yield i }
let getAns sq = sq |> Seq.head
let seqfil (a,acc) (b,curr) = if acc = curr then (a,acc) else if acc < curr then (b,curr) else (a,acc)
let pmap f l =
seq { for a in l do yield async {return f a} }
|> Seq.map Async.RunSynchronously
let pmap2 f l =
seq { for a in l do yield async {return f a} }
|> Async.Parallel
|> Async.RunSynchronously
let procseq f l = l
|> f runRules
|> Seq.reduce seqfil
|> fst
let timer = System.Diagnostics.Stopwatch()
timer.Start()
let ans1 = testlist |> procseq Seq.map // 837799 00:00:08.6251990
printfn "%A\t%A" ans1 timer.Elapsed
timer.Reset()
timer.Start()
let ans2 = testlist |> procseq pmap
printfn "%A\t%A" ans2 timer.Elapsed // 837799 00:00:12.3010250
timer.Reset()
timer.Start()
let ans3 = testlist |> procseq pmap2
printfn "%A\t%A" ans3 timer.Elapsed // 837799 00:00:58.2413990
timer.Reset()
Почему Async.Parallel код запуска очень медленно по сравнению с прямой на карте? Я знаю, что не должен видеть такой эффект, так как я только на двухъядерном Mac.
Обратите внимание, что я НЕ хочу помочь решить проблему № 14, я просто хочу знать, что случилось с моим параллельным кодом.
Зачем это делать параллельно, а затем делать это синхронно? Ваш трубопровод кажется странным. –
Потому что я не знаю, как получить значения? У меня создалось впечатление, что Async.Parallel дает вам список, настроенный для параллельной обработки, а затем Async.RunSynchronously запускает последовательность Async.Parallel-ized и ждет ее завершения (но она обрабатывается параллельно). –