Bu yüzden, tembel bir şekilde prim üretmek için çalışıyordum ve bunların hepsi eşdeğer bir şekilde çalışan bu üç tanımla ortaya çıkmıştı - sadece her yeni tam sayı 'un önceki tüm faktörler arasında bir faktör olup olmadığını kontrol ediyor asal: bu asal sayısı sırasına çalışma gerektirir ben düşünüyorum her tamsayı (için f_ = f (const True)
recomputing önler beriHaskell stili/verimlilik
primes1 :: [Integer]
primes1 = mkPrimes id [2..]
where mkPrimes f (x:xs) =
if f (const True) x
then
let g h y = y `mod` x > 0 && h y in
x : mkPrimes (f . g) xs
else
mkPrimes f xs
primes2 :: [Integer]
primes2 = mkPrimes id (const True) [2..]
where mkPrimes f f_ (x:xs) =
if f_ x
then
let g h y = y `mod` x > 0 && h y in
x : mkPrimes (f . g) (f $ g $ const True) xs
else
mkPrimes f f_ xs
primes3 :: [Integer]
primes3 = mkPrimes [] [2..]
where mkPrimes ps (x:xs) =
if all (\p -> x `mod` p > 0) ps
then
x : mkPrimes (ps ++ [x]) xs
else
mkPrimes ps xs
Yani bana öyle geliyor primes2
, primes1
biraz daha hızlı olmalı biz şimdiye kadar bulduğumuz, ve sadece ne zaman şifrelediğimizi yeni bir baştan çıkarmak.
Sadece bilimsel olmayan testlerden (GHCi içinde take 1000
çalıştıran) o primes3
çalışır hızlı primes2
daha gibi görünüyor.
Ben bundan bir ders alır ve ben bir dizide bir operasyon olarak bir işlev temsil edebilir, ben verimlilik için ikinci bir biçimde uygulamak gerektiğini varsayalım, veya başka bir şey oluyor burada var mıdır ?
all' muazzam overkill 'çağırarak burada primes3'' in (Şimdiye kadar biliyoruz eminim) - böylece aynı asal listesi kullanılabilir - yalnızca alarak yukarıda '' ait sqrt' x' yeterli değildir asal inşa edildiği - fonksiyonu basit bir filtre haline gelir: 'primes4 = 2: filtre (\ x> tüm ((/ = 0) (rEM x)) $ takeWhile ((<= x) (^ 2)) primes4..) [3,5 ..] '(n^1.45)' ampirik, 'de n 'asal üretilen O' yaklaşık çalışan - * sorunuzu her üç * versiyonları kuadratik bakmak - olursa olsun onlar hala işlevlerini nasıl inşa Sadece sqt x'nin altındakiler yerine * tüm * primleri ile test edin. –