gpt4 book ai didi

haskell - 递归函数的内联优化,借助 where 子句(在 Haskell 中)

转载 作者:行者123 更新时间:2023-12-04 08:01:09 24 4
gpt4 key购买 nike

序幕

  • Link 1这个帖子说:

  • "For a self-recursive function, the loop breaker canonly be the function itself, so an INLINE pragma is always ignored," according to the GHC manual


  • Link 2这个答案描述了一种通过 GHC 内联进行优化的方法。
  • Link 3这个(不相关的)帖子解释了编译器无论如何都可以自由地拒绝显式的内联建议。或者也许通过 -O2编译器的标志达到与下面显示的优化版本相同的效果?

  • 示例代码
    (如链接 2 所示)
    --PRE-OPTIMIZED VERSION--
    func :: (a -> a) -> [a] -> [a]
    func f [] = []
    func f [x] = [x]
    func f (x:s:xs) = x:(f s):(func f xs)

    ----OPTIMIZED VERSION----
    func :: (a -> a) -> [a] -> [a]
    func f = loop
    where
    loop [] = []
    loop [x] = [x]
    loop (x:s:xs) = x : f s : loop xs

    ------Eg-USAGE----------
    > mapToEverySecond (*2) [1..10]
    [1,4,3,8,5,12,7,16,9,20]

    问题
    引用@amalloy 在 comments of Link 2 中的疑虑,当然

    f is "still implicitly passed around just as much [as explicitlypassing f in the PRE-OPTIMIZED VERSION] by the closure-creatingmachinery" ?


    顺便说一句,我正在阅读融合技术,这是链接 1 中描述的替代方法,尽管我并不试图寻求可能的最快实现来代替惯用风格。
    只是好奇 是否/如何“何处定义”技巧在 OPTIMIZED VERSION 作品中看到(如果编译器决定内联这样的函数)。
    额外的链接是最受欢迎的!

    最佳答案

    这是一个相当糟糕的示例,因为通过内联此特定代码几乎没有任何好处。但在重要的情况下,类似的模式总是会变慢。大想法是在“优化”func ,如果我写

    func myFun
    GHC 可以内联 func并得到
    let
    loop [] = []
    loop [x] = [x]
    loop (x:s:xs) = x : myFun s : loop xs
    in loop
    在这种情况下,这并不是更好,但如果 myFun 的结果被严格要求,那么它将用对已知地址的调用替换对任意地址的调用,这样更快。此外,如果 myFun被用在“有趣”的上下文中(知道传递给它的参数或对其结果做了什么),那么 GHC 可能会内联 myFun以利用这一点。

    关于haskell - 递归函数的内联优化,借助 where 子句(在 Haskell 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66459630/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com