Haskell与JVM性能比较

40

我想为一个网站编写后端系统(它将是一种自定义搜索式服务)。它需要高度并发和快速。考虑到我的并发希望,我打算使用函数式语言,如 Haskell 或 Scala。

然而,速度也是一个优先考虑的因素。http://benchmarksgame.alioth.debian.org 的结果显示,Java 几乎与 C/C++ 一样快,Scala通常相当不错,但大多数任务对于 Haskell 来说则比较慢。

有谁有使用 Haskell、Scala 和 Java 执行高度并发任务的性能基准或经验吗?

我看过一些网站,它们建议 Scala 存在内存泄漏问题,这可能对像这样长时间运行的服务非常糟糕。

在选择编写服务之前,我应该写什么,或者应该考虑哪些因素(性能和并发是最重要的)?

谢谢


6
你是否有任何理由认为你的问题与这些基准测试所解决的问题相似?而且你是否有理由认为你将能够像这些基准测试一样对代码进行优化(也就是说,非常充分的优化)?如果没有,那么这些基准测试对你来说是毫无价值的。另外请注意,在最坏情况下,Haskell 基准测试可能比 Java 基准测试慢 10 倍,但对于大多数 Scala 基准测试而言,差距要小得多。 - user395760
2
如果你在评估 Haskell,那么请使用 GHC v7,它使用 LLVM 生成更快的代码。由于 LLVM,Haskell 的性能应该会有巨大的提升。请注意,目前仍然有一些发行版只提供 GHC v6,特别是 Mac OS X 上的 MacPorts。 - Jeff Burdges
1
不用担心Scala的内存泄漏问题。在内置的actors实现中,这曾经是一个问题,但我相信这个问题现在已经得到解决,并且 Akka 正在成为首选的actors库。 - Kipton Barros
1
@igouy:是的,但据我所见,他们并没有使用LLVM代码生成器,这需要使用“-fllvm”选项显式启用。 - hammar
4
“你有什么理由认为你能像这些基准测试一样充分优化你的代码(也就是说,非常充分)?”换句话说,“你能写出像Don Stewart一样优秀的Haskell代码吗?” - igouy
显示剩余14条评论
6个回答

22

这个问题表面上涉及使用GHC编译的代码性能与在JVM上运行的代码的比较,但是还有很多其他因素需要考虑。

团队

  • 是一个团队在开发这个项目,还是只有你一个人?
    • 这个团队对这些语言的熟悉程度如何?
    • 这是你们想要投入时间学习的语言吗?
  • 谁来维护它?

行为

  • 这个项目预计会持续多长时间?
  • 如果有停机时间,什么时候会接受?
  • 这个程序将进行什么样的处理?
    • 是否有众所周知的库可以帮助你完成这个任务?
    • 你愿意自己编写库吗?在这种语言中这样做有多困难?

社区

  • 你计划从开源中获得多少资源?
  • 你计划向开源社区贡献多少?
  • 社区有多活跃和有帮助
    • 在StackOverflow上
    • 在irc上
    • 在Reddit上
    • 在开源组件上工作,你可能会使用到这些组件

工具

  • 你需要一个集成开发环境吗?
  • 你需要代码性能分析吗?
  • 你想进行什么样的测试?
  • 语言文档和你将使用的库的文档有多有帮助?
  • 是否有工具可以满足你甚至还不知道自己需要的需求?

有一百万个以上的因素需要考虑。无论您选择Scala、Java还是Haskell,我几乎可以保证您将能够满足性能需求(这意味着,在任何这些语言中满足性能需求可能需要大约相同数量的智力)。Haskell社区以乐于助人而闻名,而我对Scala社区的有限经验与Haskell非常相似。就个人而言,与至少具有一流函数的语言相比,我开始觉得Java相当令人不快。此外,还有更多的Java程序员,导致网络上关于Java的信息繁多,这或许是好事(您需要了解的内容更容易找到),或者是坏事(需要筛选的噪音很多)。

简而言之,我相信性能大致相同。请考虑其他标准。


Haskell社区以极具帮助性而著称,而我的Scala社区的经验与Haskell类似。- 我根本不了解Haskell社区,但我与Scala社区的经验非常糟糕。你是不是把“有帮助的”中的“不”漏掉了?或者你找到了Scala社区中非常友好的子集吗?如果是这样,能给我指引一下吗?我需要在Scala编码方面得到一些帮助。 - kittylyst
1
@kittylyst:在 #scala irc 和 StackOverflow 上使用 scala 标签提问对我非常有帮助。有时需要谨慎以产生良好的体验。例如,我小心地措辞 我的最新 Scala 问题 避免听起来具有对抗性。此外,在提问时,有时候你必须敞开心扉,接受一个可能性,那就是你只是没有用“Scala 的方式”思考;如果/当人们告诉你这一点时,请不要感到冒犯。 - Dan Burton

10

你应该选择你最擅长的语言,并且该语言对你要实现的内容有最好的库支持(注意Scala可以使用Java库)。如果你足够学会使用,Haskell可能非常适合你的需求,同样适用于Scala。如果你不熟悉这种语言,很难编写高性能代码。

我的观察是,在Scala中可以编写比Haskell更快速且更紧凑的高性能并行代码。但是,你不能只是在任何语言中使用最显然的想法,然后期望它可以快速运行。

Scala不再有与actor相关的内存泄漏问题,除非你在使用默认的actors的情况下受到CPU限制,因此消息产生得比消费快,或者你忘记处理所有消息。这是一个设计选择而不是错误,但对于某些类型的容错应用程序来说可能是不正确的设计选择。Akka通过使用不同的actor实现来克服这些问题。


6
看一下这个对比。在某些问题上,ghc 和 java7-server非常接近。对于同样多的问题,在两者之间有2倍的差异,只有一个问题有5倍的差别。这个问题是k-核苷酸问题,因为stdlibs中没有好的散列表实现,所以GHC版本使用了手动编写的可变哈希表。我敢打赌,现在一些新的数据结构提供的哈希表要比那个更好。
无论如何,如果您的问题更像第一组问题(纯计算),则性能差异不大。如果您的问题更像第二组问题(通常需要使用突变),即使使用突变,您也可能会注意到性能差异。但是,这真的取决于你在做什么。如果您正在搜索大型数据集,则倾向于受IO限制。如果您正在优化不可变结构的遍历,则Haskell很好。如果您正在突变复杂的结构,则可能会付出更高的代价(具体情况而定)。
此外,GHC的轻量级绿色线程可以使某些类型的服务器应用程序极其高效。因此,如果服务/切换本身成为瓶颈,则GHC可能会占据优势。
关注速度很好,但真正的区别在于使用任何已编译语言和任何脚本语言之间的区别。除此之外,在某些HPC情况下,我们谈论的差异才真正会有所作为。

1
但真正的区别在于使用任何编译语言和任何脚本语言之间,除非“你倾向于受到IO限制”。 - igouy
@igouy:嘿,你说得对。但即使这样,WideFinder 2的结果仍然被编译语言所主导:http://wikis.sun.com/display/WideFinder/Results - sclv

4
枪击测试基准假定所有实现都使用相同的算法。这给予C/C++(在大多数情况下是参考实现)和类似它的语言最大优势。如果你采用适合不同语言的不同方法,这就被取消资格。
如果你从自然描述在Haskell中表现最好的问题开始(或非常像它的语言),那么Haskell会在这些语言中表现最好。
通常当人们谈论使用并发时,他们忘记了他们这样做的原因是为了使应用程序更快。很多例子中使用多个线程并不比单个线程快多少,或者慢得多。我建议您从高效的单线程实现开始,尽可能调试/优化它,然后考虑哪些部分可以并行处理。如果它没有比一个CPU更快,那就不要将其并发化。
IMHO:性能是您的最高优先级(在正确性之后),并发只是作业练习中的一个优先级。

6
不正确- C/C++不是“参考实现”。例如,pi-digits任务取自Haskell程序,thread-ring任务取自Erlang程序,fannkuch取自Lisp程序,binary-trees和n-body取自Java程序,...我不编写C/C++,因此无法将其用作参考实现。 - igouy
事实上,我的实践是通过使用Clean、C#和PHP编写程序来测试任务的适用性。 - igouy
1
Lawrey 暗示的是这样的语句:"每个程序必须像C#程序一样实现4个单独的函数/过程/方法。" 一般来说,不遵循这些说明的条目将被拒绝。(顺便说一下,现在看着Scala条目被接受或拒绝的原则是什么呢? :)) - applicative
@applicative - 请展示Peter Lawrey实际说过这句话的地方,或者其他让我们相信你对他的想法有深入了解的理由。同时,请具体指出某个Scala程序的具体问题,以便进行检查,而不是含糊的暗示。 - igouy

3

有没有人对使用Haskell、Scala和Java执行高并发任务的性能基准/经验有了解的?

您的具体解决方案架构很重要 - 它非常重要


2
我会选择Scala,但是我一直在尝试Scala,所以我的偏好肯定会是Scala。然而,我看到过很多用Java编写的高性能多线程应用程序,所以我不确定为什么这种应用程序的性质需要使用FP。我建议你根据你的应用程序需求在Scala和Haskell中编写一个非常小的模块,并在你的设置上测量性能。而且,我可以加入Clojure吗? :-) 我怀疑你可能想要继续使用Java,除非你正在考虑从你选择的语言中获益的其他功能。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接