Compiler construction F#编译器问题

Compiler construction F#编译器问题,compiler-construction,f#,compiler-optimization,Compiler Construction,F#,Compiler Optimization,关于F#编译器的几个问题 1)noframework做什么?我用它编译,但我仍然需要.NET4.0(我想它可能允许一个端口到早期版本?),它是否删除了F#依赖性 2)F#--optimize+启用了哪些优化?都是吗?如果是,它们都是什么 3)tailcall的优点/缺点是什么?我知道x64过去常常忽略。tailcall有时,我很好奇是否还有其他问题,或者这些问题是否仍然存在 4)什么是交叉优化,它做什么 5)以下是一些基于记忆的快速答案。(您可以随时浏览编译器代码以了解更多详细信息。) 1) 它

关于F#编译器的几个问题

1)noframework做什么?我用它编译,但我仍然需要.NET4.0(我想它可能允许一个端口到早期版本?),它是否删除了F#依赖性

2)F#--optimize+启用了哪些优化?都是吗?如果是,它们都是什么

3)tailcall的优点/缺点是什么?我知道x64过去常常忽略。tailcall有时,我很好奇是否还有其他问题,或者这些问题是否仍然存在

4)什么是交叉优化,它做什么


5)

以下是一些基于记忆的快速答案。(您可以随时浏览编译器代码以了解更多详细信息。)

1) 它不试图隐式使用任何mscorlib/FSharp.Core程序集,从而允许针对不同的框架。因此,当您明确地将Silverlight mscorlib/FSharp.Core引用到目标Silverlight时,可以使用此选项

2) 是的,几乎所有的,我不知道它们都是什么。您可以查看opt.fs

3) 调试-在“调试”模式下使用VS时,会传递
--tailcalls-
,以关闭tailcalls并保留所有堆栈帧,以便更轻松地进行调试

4) FSharp可以跨程序集边界进行内联和其他优化。这对于已发布的库来说可能是危险的,因为如果A引用B和A是使用交叉优化编译的,然后部署,然后有人更改/重新部署B,则A可能会“调用”“旧”B中的方法,因为B中的代码已内联到A中,因此A仍然具有“旧B”代码,除非重新编译A。这在实践中并不重要,但“典型”的情况是,如果您有许多相互依赖但可独立分发的F#库,您需要关闭crossoptimize以摆脱脆弱的依赖关系


5) 这已经不存在了。

下面是问题2的更详细答案。F#编译器有许多优化选项,并且--optimize+启用了其中的大部分选项

阅读编译器源代码,下面是一系列内容——optimize+启用。 我也给你隐藏的旗帜,以防你想玩它们。当然,由于没有隐藏和记录,这可能会在下一版本中发生变化:

  • JIT优化(--JIT优化)
  • 局部优化(--localoptimize),例如消除死私有绑定
  • 跨模块优化(--CrossOptimization+)
  • 允许lambda函数的内联(-inlinethreshold:6)。大小大于给定threashold的大函数不会内联
  • 设置(此项没有标志)
  • 消除在调用站点分配的元组,因为函数是非载波的(--detuple:1)。有关详细评论,请参阅
  • 执行TLR(--TLR:1)。我不知道它是什么,但在网上有很多评论
  • 最终简化过程(--finalSimplify:1)第二次应用一些优化(在其他优化过程之后)
看起来--optimize+没有启用--extraoptimizationloops:1标志。它执行与最终简化过程相同的优化,但在另一个时间执行。可能没用

对于问题3,尾部调用优化对于防止堆栈溢出非常有用(当您执行许多尾部递归调用时)。这会使调试变得更困难,因此您有时可能希望将其关闭(这是VS中调试模式下的默认设置)