【问题标题】:F# compiler questionsF# 编译器问题
【发布时间】:2011-04-07 05:31:43
【问题描述】:

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

1) --noframework 有什么作用?我用它编译,但我仍然需要 .Net 4.0(我认为它可能允许端口到早期版本?)它是否删除了 F# 依赖项?

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

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

4)什么是--crossoptimize,它有什么作用?

5) is there actually a fast sublanguage or is that something really old??

【问题讨论】:

    标签: 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) 那不再存在了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多