【问题标题】:How can I determine if a function is being memoized in Haskell?如何确定 Haskell 中是否正在记忆函数?
【发布时间】:2019-05-29 00:29:10
【问题描述】:

我有一个 Haskell 程序,它在性能方面表现出非线性(比 O(n) 更糟)。

我正在尝试调查是否正在对函数进行记忆化,我可以验证一下吗?我熟悉 GHC 分析 - 但我不太确定应该查看哪些值?

解决方法就是插入一些值并观察执行时间——但这并不理想。

【问题讨论】:

  • 您可以读取 GHC 的核心输出(使用 ghc -ddump-simpl -dsuppress-all),并查找应该从其周围函数中浮动出来的 let 绑定。
  • 愿意分享一个代码 sn-p 吗?还是会分散我们的注意力?很好奇它是关于什么的。
  • 对您认为可能被重新计算的事物使用 Debug.Trace,看看它们是否多次出现

标签: haskell memoization


【解决方案1】:

据我所知,Haskell 中没有自动记忆功能。

也就是说,GHC 中似乎有一种优化,可以缓存无参数函数的值,如下所示

rightTriangles = [ (a,b,c) | 
    c <- [1..], 
    b <- [1..c], 
    a <- [1..b], 
    a^2 + b^2 == c^2]

如果您在 GHCi 中尝试以下两次,您会发现第二次调用要快得多:

ghci > take 500 rightTriangles

【讨论】:

  • Haskell 中没有“无参数函数”之类的东西。 rightTriangles 只是一个列表。惰性意味着列表中的各个 仅按需计算。当您第一次调用take 500 rightTriangles 时,必须实际计算前 500 个值(以便实际显示这些值)。对于第二次调用,前 500 个值当然仍在内存中。
  • 是的,如果“无参数函数”是指“常量应用形式”或 CAF。
  • 是的,我正在接受CAFsints = from 1 where from n = n : from (n+1) 是 CAF 的另一个示例。
【解决方案2】:

不是一个真正的答案,但仍然应该有帮助,记忆化似乎在函数“条目”方面对分析输出没有影响。用以下基本示例进行演示:

module Main where


fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

fibmemo = (map fib [0 ..] !!)

main :: IO ()
main = do
  putStrLn "Begin.."
  print $ fib 10
  -- print $ fibmemo 10

使用上面的代码,分析输出是:

                                                                             individual      inherited
COST CENTRE  MODULE                SRC                    no.     entries  %time %alloc   %time %alloc

MAIN         MAIN                  <built-in>             119          0    0.0    1.3     0.0  100.0
 CAF         Main                  <entire-module>        237          0    0.0    1.0     0.0    1.2
  main       Main                  Main.hs:(12,1)-(14,16) 238          1    0.0    0.2     0.0    0.2
   fib       Main                  Main.hs:(5,1)-(7,29)   240        177    0.0    0.0     0.0    0.0
 CAF         GHC.Conc.Signal       <entire-module>        230          0    0.0    1.2     0.0    1.2
 CAF         GHC.IO.Encoding       <entire-module>        220          0    0.0    5.4     0.0    5.4
 CAF         GHC.IO.Encoding.Iconv <entire-module>        218          0    0.0    0.4     0.0    0.4
 CAF         GHC.IO.Handle.FD      <entire-module>        210          0    0.0   67.7     0.0   67.7
 CAF         GHC.IO.Handle.Text    <entire-module>        208          0    0.0    0.2     0.0    0.2
 main        Main                  Main.hs:(12,1)-(14,16) 239          0    0.0   22.6     0.0   22.6

如果我们注释掉 fib 10 并取消注释 fibmemo 10,我们会得到:

                                                                             individual      inherited
COST CENTRE  MODULE                SRC                    no.     entries  %time %alloc   %time %alloc

MAIN         MAIN                  <built-in>             119          0    0.0    1.2     0.0  100.0
 CAF         Main                  <entire-module>        237          0    0.0    1.0     0.0    2.9
  fibmemo    Main                  Main.hs:9:1-29         240          1    0.0    1.6     0.0    1.6
   fib       Main                  Main.hs:(5,1)-(7,29)   242        177    0.0    0.0     0.0    0.0
  main       Main                  Main.hs:(12,1)-(15,20) 238          1    0.0    0.2     0.0    0.2
   fibmemo   Main                  Main.hs:9:1-29         241          0    0.0    0.0     0.0    0.0
 CAF         GHC.Conc.Signal       <entire-module>        230          0    0.0    1.2     0.0    1.2
 CAF         GHC.IO.Encoding       <entire-module>        220          0    0.0    5.3     0.0    5.3
 CAF         GHC.IO.Encoding.Iconv <entire-module>        218          0    0.0    0.4     0.0    0.4
 CAF         GHC.IO.Handle.FD      <entire-module>        210          0    0.0   66.6     0.0   66.6
 CAF         GHC.IO.Handle.Text    <entire-module>        208          0    0.0    0.2     0.0    0.2
 main        Main                  Main.hs:(12,1)-(15,20) 239          0    0.0   22.2     0.0   22.2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    • 2018-01-11
    • 2016-04-11
    • 1970-01-01
    • 2017-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多