2017-06-05 67 views
3

我有一個非常簡單的函數f :: Int -> Int,我想寫一個程序,每個n = 1,2,...,max調用f。在每次撥打電話f後,應該顯示該點以前使用的(累計)時間(以及nf n)。這如何實現?函數的重複計時

我還是很新的,以在Haskell輸入/輸出,所以這是我到目前爲止已經試過(使用一些玩具例子功能f

f :: Int -> Int 
f n = sum [1..n] 

evalAndTimeFirstN :: Int -> Int -> Int -> IO() 
evalAndTimeFirstN n max time = 
    if n == max 
    then return() -- in the following we have to calculate the time difference from start to now 
    else let str = ("(" ++ (show n) ++ ", " ++ (show $ f n) ++ ", "++ (show time)++ ")\n") 
     in putStrLn str >> evalAndTimeFirstN (n+1) max time -- here we have to calculate the time difference 

main :: IO() 
main = evalAndTimeFirstN 1 5 0 

我不太怎麼看我必須在這裏介紹時間。 (Int對於time可能必須用別的東西來代替。)

+4

將基準委託給專門的工具可能會更好, http://www.serpentine.com/criterion/ – karakfa

+0

謝謝你的鏈接!現在對我來說似乎有點太難了,所以我認爲在使用這樣的庫之前,我仍然試圖堅持一種基本的方法,因爲我想學習如何做這樣的想法。 – flawr

+2

以懶惰的語言很難做到正確和雙重的基準測試。如果你想得到準確的結果,我不建議你自己滾動。 –

回答

0

我終於找到了解決辦法。在這種情況下,我們以毫秒爲單位測量「實際」時間。

import Data.Time 
import Data.Time.Clock.POSIX 

f n = sum[0..n] 

getTime = getCurrentTime >>= pure . (1000*) . utcTimeToPOSIXSeconds >>= pure . round 

main = do 
    maxns <- getLine 
    let maxn = (read maxns)::Int 
    t0 <- getTime 
    loop 1 maxn t0 
    where loop n maxn t0|n==maxn = return() 
      loop n maxn t0 
      = do 
       putStrLn $ "fun eval: " ++ (show n) ++ ", " ++ (show $ (f n)) 
       t <- getTime 
       putStrLn $ "time: " ++ show (t-t0); 
       loop (n+1) maxn t0 
0

你可能想要這樣的東西。根據需要爲遞歸函數調整以下基本示例。

import Data.Time.Clock 
import Control.Exception (evaluate) 

main :: IO() 
main = do 
    putStrLn "Enter a number" 
    n <- readLn 
    start <- getCurrentTime 
    let fact = product [1..n] :: Integer 
    evaluate fact -- this is needed, otherwise laziness would postpone the evaluation 
    end <- getCurrentTime 
    putStrLn $ "Time elapsed: " ++ show (diffUTCTime end start) 
    -- putStrLn $ "The result was " ++ show fact 

取消打印結果的最後一行(它非常快速地變大)。

+0

到目前爲止,我已經找到類似這樣的代碼片段,但是如果你想測量所有的'n = 1,2,...,max'的時間並且不是僅僅是一個slinge, n',所以你需要在''n''上使用某種'loop',但這就是我卡住的地方。 – flawr

+0

@flawr但是你自己的代碼使用遞歸來做這樣一個循環。這可能不是最好的風格,但它的工作原理。我會在代碼中介紹對'getCurrentTime'的調用。 – chi