功能编程是否允许更好的运行时编译器优化?

use*_*855 22 performance functional-programming clojure

注意:已经将此作为Wiki.只要有一个很好的讨论,我不在乎这个问题被标记为什么.

我听说过,因为在纯函数式程序中,没有副作用和值不变,它使编译器更容易进行更多的运行时优化.这到底有多大?

如果这是真的,我的下一个问题是我们为此交易的自由损失是什么?我的意思是,在像C++/C这样的语言中,开发人员完全可以控制并且可以调整很多东西.如果我们把这份工作交给编译器,我们就失去了这个机会.这方面的好处是,即使是非专业程序员也可以编写好的代码.此外,如今在机器架构中有如此多的缓存层,甚至可能是专家也无法真正做任何有价值的事情.因此,将此作业委托给比程序员更了解底层架构的编译器是个好主意.

你有什么建议?

Pas*_*uoq 14

你看过这个"好数学,坏数学"的博文吗?

我在C,汇编和OCaml中编程.我有时会查看C编译器生成的程序集.这非常低效的.我经常注意到一个全局变量一次又一次地被重新加载,当它清楚(对于知道程序逻辑的人)它在执行函数期间不会改变,但是因为函数操纵指针,编译器不能假设变量未被触及.解决这个问题的一种简单方法是在函数开头将全局内容复制到本地,这样就可以保持C的可移植性,但是获得类似程序集的性能......

但你不应该这样做,事实上,使用更高级别的语言,你也没有,因为有更少的指针,强制转换和其他低级构造,让你在接近硬件时我想但实际上却妨碍了自动优化.


Chr*_*ith 9

需要明确的是,仅仅因为函数式语言的编译器可以更好地进行优化并不意味着它实际上就是这样.根据定义,任何疯狂的优化都会导致运行时出现意外行为,这几乎肯定会导致错误.所以要把一个很大的误解放在一边:理论上Haskell程序可以由编译器"免费"并行化,但实际上它们不是也不应该.

我认为编译器优化成为王者的日子已经过去了.当clockspeed是性能优化的主要瓶颈时,例如循环展开是必不可少的.但是,对于绝大多数应用程序而言,问题不是原始CPU速度,而是其他因素,例如网络带宽,磁盘IO和/或您正在使用的算法的速度.

据我所知,没有编译器优化来重新实现代码以使用并行设计模式.换句话说,如果您使用冒泡排序与每个编译器优化,您可以想到,我正在使用快速排序.在大多数情况下,智能资金都在快速排序实施中.

函数式编程有很多价值,但"因为它们运行得更快"不应该是一个考虑因素.

  • 您的回答对并行化进行了大量处理,我不确定为什么,因为问题中根本没有提到该主题。例如,高级(不仅是函数式)语言也更有可能被自动矢量化。 (2认同)
  • 并行性是优化现代CPU的一个重要因素,这些CPU趋向于拥有越来越多的内核 (2认同)

ima*_*ima 9

没有副作用和值不变异,它使编译器更容易进行更多的运行时优化

从某种意义上说,是的 - 直到你意识到副作用和可变值本身就是优化.

  • 一个足够聪明的编译器可能会推断出正在调用返回变更复制函数,以便原始值永远不会再次使用(例如,由于超出范围),并将该值变为优化.反过来,当一个潜在的可变值肯定不会改变时,推断出***更难,并且可能对于除了非常简单的程序之外的所有内容都是难以处理的. (4认同)
  • 如果可以避免的话,我宁愿不“自欺欺人”,我想适当考虑您的论点,但是当您选择侮辱我而不是实际解释时,很难理解您的观点。如果您不能抽出时间详细说明那很好,但请直接说... (2认同)
  • @ima:除非你的论点是函数式程序不能使用数组,否则我也不明白你想说什么。 (2认同)
  • 事实上,有些语言可以看到一个值不再被指向,而不是将其视为写时复制,而是修改原始值并将其作为“新”值返回。这方面的一个例子是 Tcl。我只能假设对于函数式语言可以(并且可能在某处)完成相同的操作。 (2认同)

Rob*_*vey 5

在这里查看Haskell与C的比较:

http://www.haskell.org/haskellwiki/Introduction#Quicksort_in_Haskell

你会注意到Haskell verison要短得多.然而,该页面继续说,虽然c版本可能更复杂,但它也可以进行排序,而Haskell版本必须分配更多的内存才能工作.

因此,根据定义,如果您希望能够对性能进行极端微调,则c算法是更好的方法.