Моя первоначальная цель при написании этого заключалась в том, чтобы оставить минимальный след возможной. Я могу с уверенностью сказать, что эта цель была достигнута. К сожалению, это оставляет меня с довольно медленной реализацией. Чтобы сгенерировать все простые числа ниже 2 миллионов, это занимает около 8 секунд на чипе Intel 3Ghz.
Есть ли способ улучшить время выполнения этого кода с минимальной жертвой небольшого объема памяти? В качестве альтернативы, я собираюсь сделать это неправильно, глядя на нее с функциональной точки зрения?
КОД
/// 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 })
Обновление
Я изменил алгоритм и сумел сэкономить 2 секунды, но вдвое увеличил потребление памяти.
/// 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 })
Обновление
По-видимому, я использовал старый компилятор. С последней версией мой первоначальный алгоритм занимает 6.5 с, а не 8. Это довольно хорошее улучшение.