Moim początkowym celem podczas pisania tego było pozostawienie możliwie najmniejszego śladu. Mogę powiedzieć z przekonaniem, że ten cel został osiągnięty. Niestety, pozostawia mnie to raczej powolną implementacją. Generowanie wszystkich liczb pierwszych poniżej 2 milionów zajmuje około 8 sekund w układzie Intel 3Ghz.Czy można poprawić czas wykonywania tego generatora liczb pierwszych?
Czy istnieje jeszcze poprawa czasu wykonania tego kodu przy minimalnym poświęceniu na mały ślad pamięci? Alternatywnie, czy podchodzę do tego w niewłaściwy sposób, patrząc na to z operacyjnego punktu widzenia?
KOD
/// 6.5s for max = 2,000,000
let generatePrimeNumbers max =
let rec generate number numberSequence =
if number * number > max then numberSequence else
let filteredNumbers = numberSequence |> Seq.filter (fun v -> v = number || v % number <> 0L)
let newNumberSequence = seq { for i in filteredNumbers -> i }
let newNumber = newNumberSequence |> Seq.find (fun x -> x > number)
generate newNumber newNumberSequence
generate 2L (seq { for i in 2L..max -> i })
Aktualizacja
I manipulowane algorytmu i udało się ogolił 2 sekund, ale podwójne zużycie pamięci.
/// 5.2s for max = 2,000,000
let generatePrimeNumbers max =
let rec generate number numberSequence =
if number * number > max then numberSequence else
let filteredNumbers = numberSequence |> Seq.filter (fun v -> v = number || v % number <> 0L) |> Seq.toArray |> Array.toSeq
let newNumber = filteredNumbers |> Seq.find (fun v -> v > number)
generate newNumber filteredNumbers
generate 2L (seq { for i in 2L..max -> i })
Aktualizacja
Najwyraźniej używałem starego kompilatora. W najnowszej wersji mój oryginalny algorytm zajmuje 6,5s zamiast 8s. To jest znaczna poprawa.
Tylko dla kompletności, oto kilka bardziej podstawowych funkcji: http://pastebin.com/f23c064c – Juliet
To jest po prostu niesamowite! – ChaosPandion