Haskell,Scala,Clojure,如何选择高性能模式匹配和并发

2nd*_*ife 41 ocaml haskell programming-languages scala clojure

在阅读了很多关于FP的并发执行和性能优势的博客和帖子后,我最近开始研究FP.我对FP的需求在很大程度上受到我正在开发的应用程序的影响.我的应用程序是一个基于状态的数据注入到另一个子系统,其中时间非常关键(接近每秒200万个事务).我有几个这样的子系统需要测试.我正在认真考虑使用FP来实现其并行性,并希望采用正确的方法,SO上的许多帖子都谈到了Scala,Haskell和Clojure wrt语言结构,库和JVM支持的缺点和优点.从语言的角度来看,我可以学习任何语言,只要它能帮助我实现结果.

某些帖子支持Haskell进行模式匹配和语言简单,基于JVM的FP lang在使用现有Java库方面具有很大的优势.JaneStreet是OCAML的重要支持者,但我真的不确定OCAML的开发者支持和帮助论坛.

如果有人处理过这么大的数据,请分享您的经验.

Rex*_*err 51

你想快点还是想要容易

如果你想要快速,你应该使用C++,即使你使用FP原则来帮助正确.由于时序至关重要,因此对软(和硬,如果需要)实时编程的支持将非常重要.您可以确切地确定如何以及何时有时间恢复内存,并且只花费您在该任务上花费的时间.

你所说的三种语言都比近似最优手动调整的C++慢〜2-3倍,然而只有在相当传统的命令式方式中使用时.它们都使用垃圾收集,这将在您的交易中引入不受控制的随机延迟.

现在,也就是说,使用C++以防弹方式运行是很多工作.应用FP原则需要更多的样板(即使在C++ 11中),并且大多数库默认是可变的.(编辑:Rust正在成为一个很好的选择,但是足够详细地描述Rust是超出了这个答案的范围.)

也许你没有时间,可以负担得起缩减其他规格.例如,如果它不是时间而是吞吐量是至关重要的,那么你可能希望Scala胜过Clojure(参见计算机语言基准测试游戏,Scala在撰写本文时赢得了每个基准测试,并且几乎在所有情况下都具有较低的代码大小(编辑: CLBG在这方面没有任何帮助,尽管你可能会在Web Archive上找到支持这些陈述的档案)); 应该选择OCaml和Haskell用于其他原因(类似的基准测试分数,但它们具有不同的语法和互操作性等).

至于哪个系统具有最佳的并发支持,Haskell,Clojure和Scala都很好,而OCaml有点缺乏.

这几乎把它缩小到Haskell和Scala.你需要使用Java库吗?斯卡拉.你需要使用C库吗?可能是哈斯克尔.你不需要吗?然后你可以根据你喜欢的风格选择,而不必过分担心你选择错误的生活会让你的生活变得更加艰难.

  • 你能否加入一个"比C++慢2-3倍"的引用?谢谢 (12认同)
  • @Ankur - 在功能样式编程时,与C++相比,C不会增加额外的速度和巨大的额外语法负担.选择这个的唯一原因是,如果一个人使用的是没有C++编译器的平台(一些嵌入式平台,一些FPGA代码生成器等).我严重怀疑这是这种情况. (9认同)
  • @ Edmondo1984 - 我想你误解了我.我认为Google文档根本不是很好,而且我不希望包含链接,因为我认为它会产生误导或浪费人们的时间,因为他们仔细阅读并最终意识到它并不好.(我认为他们并不认为它很棒 - 只是有点兴趣,然后人们想要比作者的意思更多地阅读它.) (2认同)
  • 如今,Rust 可能是一个不错的选择。它具有类似于 Haskell 的模式匹配,并且对 FP 的支持比 C++ 好得多,但在基准测试中的表现与 C++ 差不多。 (2认同)
  • @saolof - 同意。Rust 是目前值得探索的替代方案。 (2认同)

mik*_*era 27

我用Clojure做到了这一点,由于以下原因证明它非常有效:

  • 在库中,使用JVM是一个巨大的优势.这有效地排除了Haskell和Ocaml的用途,因为我们需要轻松访问Java生态系统并与基于JVM的工具集成(Maven构建等)
  • 如果需要严格优化内部循环,可以使用纯Java.我们为一些处理大型double []数组的自定义代码执行了此操作,但99%的时间Clojure可以为您提供所需的性能.请参阅http://www.infoq.com/presentations/Why-Prismatic-Goes-Faster-With-Clojure,了解如何使Clojure变得非常快(非常技术性的视频,假设一些先验知识!).一旦开始计算开发多核的易用性,Clojure在性能上非常具有竞争力.
  • Clojure具有非常好的多核并发支持.这对于管理并发任务非常有用.请参阅http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey
  • REPL为数据的测试和探索性工作提供了一个非常好的环境.
  • Clojure是惰性的,这使得它适合处理大于内存的数据集(假设你小心不要尝试将整个数据集一次强制进入内存).在这样的环境中也有一些很好的库,最着名的是StormAleph.风暴对你来说可能特别有趣,因为它是为大量事件的分布式实时处理而设计的.

我不能说很多其他语言的经验,但我对Haskell和Scala的一些实际经验的印象是:

  • 如果您关心纯度和使用静态类型的严格函数式编程,Haskell是很棒的.静态类型可以是正确性的有力保证,因此可能使其适用于高度算法的工作.就个人而言,我发现纯FP 有点过于僵化 - 有很多次可变状态是有用的,我认为Clojure在这里有一个稍微好一点的平衡(通过允许受控的可靠性管理参考).
  • Scala是一种优秀的语言,与Clojure共享JVM的优势.对我来说,Scala更像是一个具有功能特性和非常令人印象深刻的类型系统的"更好的Java".这不是Clojure的范式转变.缺点是类型系统可能变得相当复杂/混乱.

总的来说,我认为你可以对这些中的任何一个感到满意.它可能归结为您关心JVM以及您对类型系统的看法.

  • 许多(大多数)将Scala的类型系统视为上行而不是下行. (9认同)
  • 你的5个参数中的4个也适用于Scala(除了最后一个 - Clojure是懒惰的) (5认同)
  • 虽然Clojure可以轻松使用惰性序列,但调用懒惰语言通常是指其评估策略.[Haskell在这方面比Clojure更加懒惰](http://stackoverflow.com/questions/16800255/how-do-we-do-both-left-and-right-folds-in-clojure),但是可能是这个特定问题的偏离主题. (4认同)