2017-06-05 6 views
3

私は非常に単純な関数f :: Int -> Intを持っていて、それぞれn = 1,2,...,maxに対してfを呼び出すプログラムを書いてみたいと思います。 fの呼び出しのたびに、その時点までに使用された累積時間が表示されます(nおよびf 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 

私はかなりどのように私は表示されませんここにタイミングを導入する必要があります。 (timeIntは、おそらく何か他のものに交換する必要があります。)

+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'のすべての時間を測定し、スリングだけではなく' n "の上に何らかの' loop'が必要ですが、それは私が立ち往生しているところです。 – flawr

+0

@ flawrしかし、あなた自身のコードは再帰を使ってこのようなループを行います。それはおそらく最高のスタイルではありませんが、動作します。あなたのコードに 'getCurrentTime'の呼び出しを導入したいと思います。 – chi

関連する問題