为什么 Haskell 函数执行时间测量与 GHC 时间不同?

3
我想测量Haskell执行某个函数所花费的时间,并使用TimeIt包(我也尝试了这些建议these)。但是显示的时间与应用程序实际花费的时间不同(我已经使用+RTS -sstderr选项运行了应用程序):
CPU time:   4.85s
...  
  INIT    time    0.00s  (  0.00s elapsed)
  MUT     time    0.98s  ( 61.69s elapsed)
  GC      time    0.22s  (  0.19s elapsed)
  EXIT    time    0.00s  (  0.00s elapsed)
  Total   time    1.20s  ( 61.89s elapsed)

应用程序源代码:
import qualified Data.ByteString.Lazy.Char8 as LBS
import System.Environment
import Data.Char
import Data.Int
import System.TimeIt

readChunks :: Int64 -> LBS.ByteString -> Int64
readChunks size str 
                            | LBS.null str = 0
                            | otherwise = let (chunk, rest) = LBS.splitAt size str
                                                 in do
                                                        let len = LBS.length chunk
                                                        len `seq` len + readChunks size rest



processFile :: String -> IO()
processFile name = do
    putStrLn name
    content <- LBS.readFile name
    let 
        (recNumStr, rest) = LBS.span (not.isControl) content
        recNum = LBS.readInt recNumStr
    case recNum of
        Nothing -> putStrLn "can't parse"
        Just (value, rest) -> print (value)
    let chunkSize = 100*1024*1024   

    timeIt $ print (readChunks chunkSize rest)

更新:我发现Chronograph包显示了正确的执行时间(信息来自于这个问题)。

1个回答

1

您正在进行重要的工作,但这些工作并没有被计时 - 似乎有理由认为这些工作弥补了差异,即:

putStrLn name
content <- LBS.readFile name
let 
    (recNumStr, rest) = LBS.span (not.isControl) content
    recNum = LBS.readInt recNumStr
case recNum of
    Nothing -> putStrLn "can't parse"
    Just (value, rest) -> print (value)

如果你也计算时间,那么你可能会发现大部分的差异。还要注意,在进入main之前还有其他操作(即使对于C程序也是如此)。

我已经尝试过去掉代码的这一部分,但时间并没有改变。我认为这是因为第一行长度太小了。此外,使用ghc或外部计时器测量的时间与输入文件大小呈线性关系。 - KolKir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接