C#/ F#性能比较

Vij*_* VP 54 .net c# performance f#

Web上是否有可用的C#/ F#性能比较来显示新F#语言的正确用法?

Ste*_*vev 54

自然F#代码(例如,函数/不可变)比自然(命令性/可变对象的)C#代码慢.但是,这种F#比通常的C#代码短得多.显然,有一个权衡.

另一方面,在大多数情况下,您可以实现F#代码的性能等于C#代码的性能.这通常需要以命令式或可变的面向对象的方式编写代码,配置文件并消除瓶颈.您使用与C#中使用的相同的工具:例如.Net反射器和分析器.

话虽如此,但要注意F#中的一些高效率构造会降低性能.根据我的经验,我见过以下案例:

  • 引用(与类实例变量相对),仅在执行数十亿次的代码中

  • F#比较(<=)与System.Collections.Generic.Comparer,例如二进制搜索或排序

  • 尾调用 - 仅在某些情况下无法由编译器或.Net运行时优化.如评论中所述,取决于.Net运行时.

  • F#序列比LINQ慢两倍.这是由于引用和使用F#库中的函数来实现seq <_>的转换.这很容易修复,因为你可以用一个使用Linq,PLinq或DryadLinq的相同签名来替换Seq模块.

  • 元组,F#元组是在堆上排序的类.在某些情况下,例如int*int元组,它可能需要支付使用结构.

  • 分配时,值得记住的是,闭包是一个用new运算符创建的类,它记住了访问过的变量.可能值得"解除"闭包,或者用一个明确地将被访问的变量作为参数的函数替换它.

  • 尝试使用内联来提高性能,尤其是通用代码.

我的经验是先用F#编码,然后只优化重要的部分.在某些情况下,在C#中编写慢函数可能更容易,而不是尝试调整F#.但是,从程序员效率的角度来看,在F#中启动/原型是有意义的,然后进行轮廓分析,反汇编和优化.

最重要的是,由于程序设计决策,您的F#代码最终可能比C#慢,但最终可以获得效率.

  • "这通常需要以命令式或可变的面向对象的方式编码".不,你想要突变性能,但你必须*避免*面向对象的风格,有利于Fortran风格.OOP也很慢...... (9认同)
  • 有趣的一点,但你需要检查的不仅仅是一个运行时; 使用CLI 2,x86和x64具有非常不同的尾调用; 显然,由于支持F#,它显然得到了加强,但这可能会扭曲C#配置文件. (3认同)
  • 什么是引用(与类实例变量相比)? (3认同)
  • F#并不比C#慢,反之亦然.语言没有执行性能.我们所谈论的是编译器的效率.越高级的编译器技术越多,高级语言比低级语言更优化的可能性越大,因为您通常可以更多地了解功能源.我们现在处于功能语言编程进入主流业务的地步,其中一个原因是他们的执行速度正在接近命令式语言.我们希望他们能在十年内超车. (3认同)

Ben*_*jol 11

以下是与此主题相关的一些链接:

我似乎还记得罗伯特皮克林博​​客上的另一篇文章(或者是斯科特汉塞尔曼?),最后,因为两者都坐在同一个框架上,你可以从两者中获得相同的表现,但有时你必须'扭曲'这种语言的自然表达.在我回忆的例子中,他不得不扭曲F#以获得与C#相当的性能......

  • 如果你受益于F#独有的功能,例如`inline`,那么反过来也是如此. (4认同)