Haskell内联函数可以作为参数传递吗?

yon*_*ong 8 optimization haskell

假设我将一个小函数传递fmap.可以哈斯克尔内嵌fmap产生一个小势在必行循环?如果是这样,Haskell如何跟踪f真正的功能?使用Arrow组合器可以做同样的事情吗?

Mat*_*hid 12

如果f作为参数传入,那么不,可能不是.如果f是顶级函数或本地函数的名称,则可能是.

foobar f = ... map f ...
-- Probably not inlined.

foobar = ... map (\ x -> ...) ...
-- Probably inlined.
Run Code Online (Sandbox Code Playgroud)

也就是说,我认为内联和外联之间的大多数性能差异并非来自实际内联本身,而是来自可能允许的任何其他后续优化.

对这些事情"确定"的唯一方法是实际编写代码,实际编译它,并查看生成的Core.而知道它是否有所作为(正面或负面)的唯一方法是实际对事物进行基准测试.

  • 在第一种情况下,`foobar`本身很容易内联,允许`f`也被内联. (2认同)

chi*_*chi 11

Haskell语言的定义并未强制要求Haskell实现内联代码或执行任何类型的优化.任何实现都可以自由应用它认为合适的任何优化.

话虽这么说,Haskell现在经常使用GHC运行,GHC确实优化了Haskell代码.对于内联,GHC使用一些启发式方法来决定是否应该内联.一般的建议是打开优化-O2并检查编译器的输出.您可以看到生成的Core with -ddump-simpl或汇编代码-ddump-asm.其他一些标志也很有用.

如果你看到GHC没有内联你想要的内容,你可以提供编译器{-# INLINE foo #-}相关编译指示的提示.

但是要小心谨慎地应用优化.通常,程序员会花时间优化程序的一部分,这些部分对整体性能的影响可以忽略不计.为了避免这种情况,强烈建议配置文件首先你的代码,让你知道你的程序花费了大量的时间.

  • 这是有用的建议,但它实际上并没有回答所提出的问题。 (2认同)