【问题标题】:F# compiler questionsF# 编译器问题
【发布时间】:2011-04-07 05:31:43
【问题描述】:
【问题讨论】:
标签:
compiler-construction
f#
compiler-optimization
【解决方案1】:
这里是问题 2 的更详细答案。F# 编译器有许多优化选项,而 --optimize+ 启用了其中的大部分。
从编译器源代码中读取,这里是 --optimize+ 启用的列表。
我还给你隐藏的旗帜,以防你想和他们一起玩。当然,由于它没有被隐藏和记录,这可能会在下一个版本中改变:
- JIT 优化 (--jit-optimize)
- 局部优化 (--local-optimize),例如消除无效的私有绑定。
- 跨模块优化 (--crossoptimize+)
- 允许内联 lambda 函数 (--inlinethreshold:6)。大小大于给定阈值的大函数不会被内联。
- 设置ignoreSymbolStoreSequencePoints(这个没有标志)
- 消除在调用站点分配的元组,因为函数未使用 (--detuple:1)。详细评论请见detuple.fs。
- 执行 TLR (--tlr:1)。不知道是什么,不过tlr.fs里面有很多cmets
- 最终简化传递 (--finalSimplify:1) 再次应用一些优化(在其他优化传递之后)。
看起来 --extraoptimizationloops:1 标志没有被 --optimize+ 启用。它执行与最终简化通道相同的优化,但在另一个时间。可能没用。
对于问题 3,尾调用优化对于防止堆栈溢出非常有用(当您执行许多尾递归调用时)。它使调试变得更加困难,因此有时您可能希望将其关闭(这是 VS 中的默认设置,在调试模式下)。
【解决方案2】:
这里有一些基于记忆的快速答案。 (您可以随时深入了解编译器代码以获取更多详细信息。)
1) 通过不尝试隐式使用任何 mscorlib/FSharp.Core 程序集,它允许针对不同的框架。所以你在例如您明确引用 Silverlight mscorlib/FSharp.Core 来定位 Silverlight。
2) 是的,几乎所有,我不知道它们都是什么。你可以看看 opt.fs。
3) 调试 - 在“调试”模式下使用 VS 时,传递--tailcalls- 以关闭尾调用并保留所有堆栈帧以便于调试。
4) FSharp 可以跨程序集边界进行内联和其他优化。这对于已发布的库来说可能很危险,因为如果 A 引用 B 和 A 是使用交叉优化编译然后部署的,然后有人更改/重新部署 B,则 A 可能会“调用”“旧”B 中的方法,因为来自 B 的代码被内联到 A 中,因此除非重新编译 A,否则 A 仍然具有“旧 B”代码。这在实践中并不重要,但如果您有许多依赖但可独立分发的 F# 库,则“典型”场景需要关闭交叉优化以摆脱脆弱的依赖关系。
5) 那不再存在了。