为什么*.prof文件中有这么多反斜杠(\)?

xzh*_*zhu 16 haskell

查看*.prof使用+RTS -p启用分析的编译生成的文件,我看到很多这些子例程命名为\:

COST CENTRE           MODULE                         %time %alloc

main.\.\.\            Main                            74.1   85.8
unstreamChunks/inner  Data.Text.Internal.Lazy.Fusion  11.9    8.6 
inverseLetters.\      Main                             4.5    1.7 
main.\.\.\.(...)      Main                             2.9    1.0 
main.\.\.\.(...)      Main                             2.8    1.0 
unstreamChunks/resize Data.Text.Internal.Lazy.Fusion   1.2    0.8 
unstreamChunks/outer  Data.Text.Internal.Lazy.Fusion   1.1    0.5 
Run Code Online (Sandbox Code Playgroud)

这看起来很神秘.这些代表什么?

jos*_*uan 17

import Control.Monad

main = do
    forM_ [1..1000] $ \i ->
        if mod i 2 == 0 then putStrLn "Foo"
                        else print i
Run Code Online (Sandbox Code Playgroud)

并运行

ghc -rtsopts -prof -fprof-auto z.hs && ./z +RTS -p && cat z.prof
Run Code Online (Sandbox Code Playgroud)

然后,遵循设定成本中心的规则

COST CENTRE MODULE           %time %alloc
main.\      Main              80.0   84.4
main        Main              20.0   13.2
CAF         GHC.IO.Handle.FD   0.0    2.1
Run Code Online (Sandbox Code Playgroud)

反斜杠显示堆栈级别,您可以为每个级别设置名称

forM_ [1..1000] $ \i ->
    {-# SCC "myBranch" #-}
    if mod i 2 == 0 then putStrLn "Foo"
                    else print i
Run Code Online (Sandbox Code Playgroud)

现在

COST CENTRE MODULE           %time %alloc
myBranch    Main              90.0   84.4
main        Main              10.0   13.2
CAF         GHC.IO.Handle.FD   0.0    2.1
Run Code Online (Sandbox Code Playgroud)

(添加@trVoldemort评论)

此外,(...)似乎用于let涉及计算的分配

data T = T Int (IO ()) (IO ())
main =
   forM_ [T (mod i 2) (putStrLn "Foo") (print i) | i <- [1..1000]] $ \q ->
        let T a b c = q -- Will be `(...)`
        in  if a == 0 then b else c
Run Code Online (Sandbox Code Playgroud)

与配置文件输出

main.\        Main
 main.\.b     Main
 main.\.c     Main
 main.\.(...) Main
 main.\.a     Main
Run Code Online (Sandbox Code Playgroud)

与SCC pragma

forM_ [T (mod i 2) (putStrLn "Foo") (print i) | i <- [1..1000]] $ \q ->
     let T a b c = {-# SCC "myBind" #-} q
     in  if a == 0 then b else c
Run Code Online (Sandbox Code Playgroud)

和输出

main.\.b     Main
main.\.c     Main
main.\.(...) Main
 myBind      Main
main.\.a     Main
Run Code Online (Sandbox Code Playgroud)

  • 所以,这些都不是反斜杠,它们是伪装的lambdas.有趣. (7认同)
  • 谢谢你的回答.在旁注中,我意识到`.(...)`之后的一些`./`表示带有模式匹配的let语句(这意味着它涉及计算).例如,当你说'let(a,b)= myFunc`或`let Just x = lookup ...`等时 (2认同)