【问题标题】:Will F# perform well when writing math functions for a C# program?在为 C# 程序编写数学函数时,F# 会表现良好吗?
【发布时间】:2009-01-10 18:02:01
【问题描述】:

有谁知道与 C# 相比,F# 在性能方面的衡量标准有多好。我有一个 C# 光线追踪器,其中包含许多矢量操作、光线碰撞算法等,我认为它们可能更容易在 F# 中表达。我不是在问 F# 在表达数学问题方面有多好,这已经回答了here,而是我是否应该期待更好或更差的性能?由于光线追踪对性能的要求很高,因此即使是性能不佳的小情况也可能在错误的地方出现问题。

编辑:

似乎已经有很多关于该主题的问题我找不到(如果您实际搜索任何带有术语“F#”的内容,则没有结果)。一个好点here 是以下答案:

F# 提供了一些与性能相关的 可以产生影响的功能。

首先,实施 .NET 上的代表目前相当 效率低下,因此 F# 使用 它自己的 FastFunc 类型用于 高性能一流 功能。

其次,F# 使用 .NET 元数据 传达内联函数,以便它们 可以跨 API 导出,并且 当然,这可以显着提高 在某些情况下的表现。

最后,模式匹配可以 用 C# 表达非常费力 因为语言缺乏模式 匹配但几乎是不可能的 维护优化的 C# 代码 等价于许多非平凡的模式 火柴。相比之下,F# 编译器 积极优化模式匹配 在编译期间。

相反,C# 编译器更好 在使用 IEnumerables 优化循环时 并且更擅长优化 对值类型的计算(例如 复杂的算术)。

干杯,乔恩·哈罗普。

【问题讨论】:

    标签: c# performance f#


    【解决方案1】:

    是的,F# 会表现得更好。

    以下是用不同语言实现的单线程算法的一些性能结果(神经网络的基准激活函数方法):

    C#:

    10^7 iterations using Sigmoid1() took 3899,1979 ms
    10^7 iterations using Sigmoid2() took 411,4441 ms
    

    纯 C:

    10^7 iterations using sigmoid1: 628 ms
    10^7 iterations using sigmoid2: 157 ms
    

    F#:

    10^7 iterations using sigmoid1: 588.843700 ms
    10^7 iterations using sigmoid2: 156.626700 ms
    

    More details

    【讨论】:

    • 太棒了 :) F# 比纯 C 更快。非常好的发现!我知道 F# 通常比 C# 快,但比 C 快简直太棒了……
    • 是的,我也很惊讶。但是,我没有使用最新的 C 编译器,因此它的性能可能略胜 F#))
    【解决方案2】:

    F# 的计算行为与 C# 相同(因为它只是 IL)。只需确保将您的向量表示为一个结构 - 因为您将构建许多短暂的对象。

    度量单位对性能的影响为零,实际上在编译时度量单位信息已被完全删除。所以你实际上无法判断你的 F# 代码上面有度量单位。

    【讨论】:

      【解决方案3】:

      F# 的性能与 C# 的性能大致相同,它们都编译为 IL,这是一个重要因素(与 IronPython 和 IronRuby 不同,它们被解释,因此速度慢得多)。算法的性能更多地取决于它的实现,而不是 F# 或 C# 的选择,因为 F# 将有助于在几行代码中实现它,与在 C# 中相比,在 F# 中发现优化的机会要大得多。

      这篇文章对性能问题也有类似的看法: http://diditwith.net/2008/04/03/ApplesAndOranges.aspx

      【讨论】:

        【解决方案4】:

        也许你已经知道了,但也许还没有。

        Google 上的名字是“Luke Hoban”,他用 C# 3.0 制作了一个光线追踪器,现在在微软的 F# 团队工作。

        另请参阅:http://blogs.msdn.com/lukeh/http://blogs.msdn.com/lukeh/archive/2007/04/03/a-ray-tracer-in-c-3-0.aspx

        他应该知道的。

        【讨论】:

        • 他承认自己光线追踪器效率不高,他似乎更多地将其作为练习而不是创建一个好的光线追踪器。
        • 也许你可以给他发邮件问你的问题?
        • 是的,那个光线追踪器效率不高,但它对 Linq 来说是一个很好的实验。
        【解决方案5】:

        事实上,理论上,x86机器只能执行命令式的x86汇编,因此,理论上可以命令式地实现函数式语言的性能。因此,您可以编写与 F# 同类程序相同或更好的 C# 程序。这里的关键字是can。这并不意味着所有 C# 程序都比 F# 程序或类似的程序更好。通常,在大多数问题中,F# 的性能是可以接受的。在某些情况下,F# 的性能远远落后于 C#,但通常对于大多数应用程序来说是可以的。但是,如果您想对代码实际执行的操作进行细粒度控制,那么函数式语言不适合您。 C# 中的优化机会比 F# 中的多。顺便说一句,我所说的 F#,并不是指编写命令式代码,而是普通的函数式方法(如果你想编写命令式代码,我认为 F# 没有多大意义)。

        【讨论】:

        • 理论上你是对的,实际上 F# 比 C# 具有更好的性能,因为它进行了更积极的优化,F# 只是输出更好的 IL,有时甚至更好。
        • 在实践中,结果很大程度上取决于您所写的内容。有两种情况 F# 更好,也有它落后 的情况。顺便说一句,我的比较更多是关于“Functional F#”和“C#”。有些问题不能有效地表达为函数的组合。
        • “如果您想对代码实际执行的操作进行细粒度控制,函数式语言不适合您”。你是说纯洁。 F# 不纯。 F# 为您提供了非常精细的控制,当然可以与 C# 媲美。
        【解决方案6】:

        我最初的反应是,由于 C# 和 F# 都输出 MSIL,因此性能将相同。但是您使用的结构可能会产生不同的 IL。该主题已在链接here on SO 中进行了详细讨论。

        【讨论】:

          【解决方案7】:

          F# 更适合并行编程。所以开箱即用它可以比 C# 更快(在多核/cpu 上)。

          但话又说回来,您可以优化 C# 以同样使用它,但这需要更多的工作。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-10-03
            • 1970-01-01
            • 2022-10-21
            相关资源
            最近更新 更多