Il mio obiettivo iniziale quando scrivevo questo era di lasciare il minimo ingombro possibile. Posso dire con certezza che questo obiettivo è stato raggiunto. Sfortunatamente, questo mi lascia un'implementazione piuttosto lenta. Per generare tutti i numeri primi sotto i 2 milioni occorrono circa 8 secondi su un chip Intel 3Ghz.È possibile migliorare il tempo di esecuzione di questo generatore di numeri primi?
C'è comunque qualche modo per migliorare il tempo di esecuzione di questo codice con il minimo sacrificio sul piccolo spazio di memoria? In alternativa, sto andando in questo modo nel modo sbagliato quando si guarda da un punto di vista funzionale?
CODICE
/// 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 })
Aggiornamento
ho ottimizzato l'algoritmo e sono riuscito a radersi 2 secondi ma il consumo doppio di memoria.
/// 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 })
Aggiornamento
A quanto pare, stavo usando un vecchio compilatore. Con l'ultima versione il mio algoritmo originale richiede 6,5 anziché 8 secondi. Questo è un bel miglioramento.
Solo per completezza, ecco alcune funzioni più prime: http://pastebin.com/f23c064c – Juliet
Ora è semplicemente fantastico! – ChaosPandion