递归函数的内联优化,借助where子句(在Haskell中) 序曲 这篇文章说:
“对于自递归函数,环路断路器可以 只能是函数本身,因此内联pragma总是被忽略,”根据GHC手册递归函数的内联优化,借助where子句(在Haskell中) 序曲 这篇文章说:,haskell,optimization,inline,ghc,Haskell,Optimization,Inline,Ghc,“对于自递归函数,环路断路器可以 只能是函数本身,因此内联pragma总是被忽略,”根据GHC手册 该答案描述了GHC通过内衬进行优化的方法 这篇(不相关的)文章解释了编译器无论如何都可以自由地拒绝显式内联建议。或者,将-O2标志传递给编译器可以获得与下面所示的优化版本相同的效果 示例代码 (如链接2所示) 问题 引用@amalloy的怀疑,当然 f仍然是“隐式传递的,与显式传递的一样多” 通过闭包创建程序在预优化版本]中传递f 机械“ 另一方面,我正在阅读fusion技术,这是链接1中描
-O2
标志传递给编译器可以获得与下面所示的优化版本相同的效果
问题 引用@amalloy的怀疑,当然
f
仍然是“隐式传递的,与显式传递的一样多”
通过闭包创建程序在预优化版本]中传递f
机械“
另一方面,我正在阅读fusion技术,这是链接1中描述的一种替代方法,尽管我并不试图寻找最快的实现来代替惯用风格
只是好奇优化版本中的“where definition”技巧是否/如何工作(如果编译器决定内联这样的函数)
额外的链接是最受欢迎的 这是一个相当糟糕的例子,因为内联这段特定代码几乎没有什么好处。但在重要的情况下,类似的模式总是会减慢速度。最重要的是,在“优化的”
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
,以利用这一点。很吸引人,那么程序员是否必须传递明确的标志才能严格要求myFun?另外,请给出一些例子,说明内联可以真正产生重大影响,可能会扩展到GHC知道参数的情况下——可能不仅仅是它们的(具体)类型——第一个相当于\f->\list->case list of{…func…}
,而第二个相当于let{循环=清单-> {…循环…}的列表(在\f->循环)。GHC中的优化将将前者转换为后者。一般来说,这增加了共享(<代码> f<代码>),并提供了内联的机会;语用工作与C++的代码>内联< /代码>有很大的不同。
let
loop [] = []
loop [x] = [x]
loop (x:s:xs) = x : myFun s : loop xs
in loop