簡體   English   中英

Haskell在這里做了什么樣的優化?

[英]What kind of optimizations does Haskell do here?

因此,我當然是Haskell Newbie的成員,但是到目前為止,我非常喜歡它,因為我最近一直在進行素數激增。 (這是讓我着迷的原因)

我有這個相對基本的腳本。 即使它效率不高,它也可以正常工作。 那不是我的問題。 這是我的腳本:

import System.Environment


oddFactors p = [x | x<- [3,5..floor (sqrt (fromIntegral p))], p `mod` x == 0]
prime x = oddFactors (2^x -1) == []

main = do
    args <- getArgs
    print (prime (read (head args) :: Int))

就像我說的那樣,很簡單。 奇數oddFactors3sqrt(p)奇數,如果它是p的因數,則將其添加到列表中。

primes調用2^x -1上的oddFactor ,並檢查結果列表是否等於空列表。

奇怪的是,它似乎已經被優化了。 對於primes ,例如61,我的程序需要49秒才能運行並返回True。 但是,如果我執行60或62,則需要運行0.005秒並返回False。 這些是正確的返回值,但是我很好奇它是否經過某種方式的優化,因為它知道它只是在尋找一個匹配[]的列表,並且在找到一個列表之后,它會返回false,因為列表永遠不會是[]

冗長的問題,但到目前為止,我也願意對我的代碼提出任何建議。 我大約兩個小時前就接過Haskell,所以要好:)

編輯 :我當然知道我可以使用更好的東西作為初等性測試,例如Miller-Rabin,但這不是重點;)

測試list == []將評估list作為需要檢查的空虛只有盡可能多的list 從技術上講,盡可能多地發現list的最外層構造函數(可以是:[] ),使list成為弱頭范式(WHNF)。

例如, (error "hello" : error "world") == []將返回False而不評估error表達式。

這是由於表達式被懶惰地求值以及(==)的定義以自然方式使用模式匹配導致的:

[]     == []     = True
[]     == _      = False
_      == []     = False
(x:xs) == (y:ys) = x==y && xs==ys

相比之下,如果定義是

[]     == []     = True
[]     == (y:ys) = []==ys && False
(x:xs) == []     = xs==[] && False
(x:xs) == (y:ys) = x==y && xs==ys

那么list == []將在返回False (或更確切地說,整個列表spine )之前強制執行整個列表的計算。

Haskell懶惰地評估函數調用。 這意味着它首先在求值時嘗試找出== “ call”,例如說prime 60它試圖找到1152921504606846975的奇數因子。 在評估時,它會歸入==定義,對於一個空列表,它僅試圖找出是否存在至少一個元素。 所以有效地它只會評估

1152921504606846975 `mod` 3 == 0

由於這是真的,所以它甚至不評估列表的其余部分:它已經知道3:(stuff) == []False ,而不管(stuff)可能會得出什么結果。

當您將其傳遞給61 ,它會嘗試找到一個為質數的2305843009213693951的奇數因子,因此它必須擴展對孔列表的理解,才能確定其為空。 這就是為什么要花這么長時間的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM