F#似乎比其他语言要慢...我该怎么做才能加快速度? [英] F# seems slower than other languages... what can I do to speed it up?

查看:75
本文介绍了F#似乎比其他语言要慢...我该怎么做才能加快速度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我喜欢F#;我真的,真的.被函数式编程"错误咬伤后,我强迫自己在有机会时使用它.实际上,我最近(在一个星期的假期中)用它来编写一个不错的AI算法.

I like F# ; I really, really do. Having been bitten by the "functional programming"-bug, I force myself to use it when I have the opportunity to. In fact, I recently used it (during a one week vacation) to code a nice AI algorithm.

但是,到目前为止,我的尝试(请参阅与我的第一次尝试相关的一个问题这里)似乎表明,尽管毫无疑问……F#的执行速度是我使用过的所有语言中最慢的.

However, my attempts so far (see a SO question related to my first attempt here) seem to indicate that, though undoubtedly beautiful... F# has the slowest execution speed of all the languages I've used.

我在代码中做错了吗?

Am I doing something wrong in my code?

我在博客帖子中详细解释了我的工作,并且在我的实验中,我看到OCaml和其他人的运行速度是F#的5到35倍.

I verbosely explain what I did in my blog post, and in my experiments, I see OCaml and the rest of the group running anywhere from 5x to 35x faster than F#.

我是唯一有这种经历的人吗?我感到最令人沮丧的是,我最喜欢的语言也是最慢的一种语言-有时到目前为止...

Am I the only one with such experiences? I find it disheartening that the language I like the most, is also the slowest one - sometimes by far...

编辑:直接GitHub链接,代码存在的地方语言形式...

EDIT: Direct GitHub link, where the code lives in various language forms...

EDIT2 :多亏了Thomas和Daniel,速度大大提高了:

EDIT2: Thanks to Thomas and Daniel, speed improved considerably:

  • 最快的速度提升:从"ref"变为"mutable"达到了惊人的30%.
  • 删除异常并使用while/flagChecks可以再得到16%.
  • 从受歧视的工会改成枚举的比例又提高了5%.
  • 内联"给0.5-1%

EDIT3 :Jon Harrop博士加入了这场战斗:通过使ScoreBoard直接对数据的枚举"版本进行操作,可将速度提高60%.现在,命令式F#的运行速度比C ++慢3-4倍,这对于基于VM的运行时来说是一个很好的结果.我认为问题已经解决-谢谢大家!

EDIT3: Dr Jon Harrop joined the fight: 60% speedup, by making ScoreBoard operate directly on the "enumerated" version of the data. The imperative version of F# now runs 3-4 times slower than C++, which is a good result for a VM-based runtime. I consider the problem solved - thanks guys!

EDIT4 :合并所有优化之后,这些就是结果(F#以命令式样式到达C#-现在,如果我也可以对功能样式做一些事情!)

EDIT4: After merging all optimizations, these are the results (F# reached C# in imperative style - now if only I could do something about functional style, too!)

  • real 0m0.221s:那是C ++
  • 真正的0m0.676s:那是C#(命令式,C ++镜像)
  • 真正的0m0.704s:那是F#(命令式,C ++镜像)
  • 真正的0m0.753s:那是OCaml(命令式,C ++镜像)
  • 真实0m0.989s:这是OCaml(功能正常)
  • 真正的0m1.064s:那是Java(必须)
  • 真实的0m1.955s:那是F#(实用的)

推荐答案

除非您可以提供合理大小的代码示例,否则很难说清.无论如何,命令式F#版本应与命令式C#版本一样高效.我认为一种方法是对这两种方法进行基准测试,以查看造成差异的原因(然后有人可以帮助使其更快一点.)

Unless you can give a reasonably sized code sample, it's difficult to tell. Anyway, the imperative F# version should be as efficient as the imperative C# version. I think one approach is to benchmark the two to see what is causing the difference (then someone can help with making that bit faster).

我简要地看了看您的代码,这里有一些(未经品尝的)建议.

I briefly looked at your code and here are some assorted (untested) suggestions.

  • 您可以将枚举的联合Cell替换为枚举(这意味着您将使用值类型和整数比较,而不是引用类型和运行时类型测试):

  • You can replace discriminated union Cell with an enum (this means you'll use value types and integer comparison instead of reference types and runtime type tests):

type Cell =    
  | Orange = 1
  | Yellow = 2
  | Barren = 3

  • 您可以将一些琐碎的功能标记为inline.例如:

  • You can mark some trivial functions as inline. For example:

    let inline myincr (arr:int array) idx =
      arr.[idx] <- arr.[idx] + 1
    

  • 不要对控制流使用异常.这通常是在OCaml中完成的,但是.NET异常很慢,应该仅用于异常.您可以将样本中的for循环替换为while循环和可变标志,或者使用尾部递归函数(将尾部递归函数编译到循环中,因此即使在命令式解决方案中也将是高效的) ).

  • Don't use exceptions for control-flow. This is often done in OCaml, but .NET exceptions are slow and should be only used for exceptions. You can replace the for loop in your sample with a while loop and a mutable flag or with a tail-recursive function (a tail-recursive function is compiled into a loop, so it will be efficient, even in imperative solution).

    这篇关于F#似乎比其他语言要慢...我该怎么做才能加快速度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆