Haskell: 函数组合 (.) 和函数应用 ($) 在性能方面有何区别?

6
在Haskell中,当性能很重要并且使用美元符或点号都是有效的选项时,哪个更好?一个会比另一个获得更好的性能吗?
例如,给定(foo . bar. baz) valuefoo $ bar $ baz value,哪个更快?

你能详细解释一下,并举个例子吗? - thefourtheye
1
如果你能找到一个它们在性能上有差异的例子,我会感到惊讶。 - augustss
2
你可以在这里尽可能详细地阐述,但基于它们的性能不同只是荒谬的事实,答案最终是“不”。坦白地说,这就像问“++i”或“i++”哪个更快;当然,在没有微不足道的优化的情况下,其中一个可能更快,但在任何合理的编译器下,你不会从这样的琐事中获得性能提升。 - alternative
当然你是指 (foo . bar . baz) value - dfeuer
@Bergi 这个对可读性的影响太大了,我不太喜欢。 - Mickael Bergeron Néron
显示剩余2条评论
1个回答

15
如果您使用优化(-O2)进行编译,GHC几乎肯定会内联.$,并在两种情况下产生foo (bar (baz value))(然后进一步优化)。“几乎”只是为了保险起见;内联是GHC执行的最基本的优化之一,而.$都非常简单,内联它们应该总是胜利的,但我可能没有考虑到某些特殊情况。(我能想到的一个困难的内联情况是当它们被部分应用或传递给高阶函数时,但这不是给出的示例;或者可能有一个rewrite rule在内联之前触发,并且仅涵盖其中一种情况。)

然而,您始终可以使用Criterion在特定情况下进行测试。您还可以通过要求GHC输出Core文件验证是否进行了内联。


“几乎肯定”是什么意思?编译器不会内联的情况有哪些? - Mickael Bergeron Néron
@MickaelBergeronNéron 我已经编辑了答案,使其更加明确。 - Alexey Romanov
列表呢?每次应用或组合之间是否会创建中间列表?流融合呢? - CMCDragonkai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接