2011-06-05 49 views
52

我们将编写一个使用Clojure的并发程序,它将从大量的传入邮件中提取关键字,并将与数据库进行交叉检查。并发模型:Erlang vs Clojure

我的一个队友建议使用Erlang编写这个程序。

这里我想说明一些我对函数式编程的新东西,所以我有点怀疑clojure是编写这个程序的好选择,还是Erlang更适合。

+0

是不是Erlang字符串处理不理想? (为了避免并发讨论...) – kotarak 2011-06-05 21:00:56

+7

在我看来,如果你误用它,Erlang中的字符串处理只是次优的。例如,处理二进制文件非常有效。 – 2011-06-06 10:08:56

+0

Erlang的语法很奇怪:http://damienkatz.net/2008/03/what_sucks_abou.html – 2011-06-07 20:07:03

回答

45

这两种语言和运行时采取不同的并发:

  • 二郎结构方案,作为许多轻量级进程彼此之间的通信。在这种情况下,您可能会有一个主进程将作业和数据发送给许多工作人员以及更多进程来处理结果数据。

  • Clojure倾向于使用通用数据结构来共享数据和状态的设计。这听起来特别适用于许多线程访问相同数据(只读)并且共享很少可变状态的情况。

您需要分析您的应用程序以确定哪种模型最适合您。这也可能取决于您使用的外部工具 - 例如,数据库处理并发请求的能力。

另一个实际的考虑是clojure运行在许多开源库可用的JVM上。

+5

很好的答案。但请注意,即使共享状态是可变的,Clojure并发STM模型也同样适用。事实上,协调对共享可变状态的更改是Clojure STM方法的主要动机。 – mikera 2011-06-06 17:58:38

+0

在我有限的经验中,“许多线程访问相同的数据(只读)并且共享很小的可变状态”已经覆盖了我曾试图解决的99%的问题。 – FUD 2014-11-18 07:04:19

8

Clojure是运行在Java JVM上的Lisp。 Erlang的设计始终是高度容错和并发的。

我相信任务可以用这些语言和许多其他语言来完成。你的经验将取决于你对问题的理解程度以及你对语言的了解程度。如果你对这两者都是新手,那么无论你选择哪一个,我都会说这个问题会很有挑战性。

你有没有想过像Lucene/Solr?这是用于索引和搜索文档的好软件。我不知道“交叉检查”对于您的情况意味着什么,但这可能是一个很好的解决方案。

+2

我听说过很多关于Clojure的顶级并发模型,但Erlang的声誉更好。这就是我怀疑的原因。虽然我有点偏向Clojure,但我不想从头开始,后来面临陷阱。至于交叉检查,我的意思是说,邮件中的这些关键字将在字典中搜索以对邮件进行排序。 – 2011-06-05 16:32:32

+0

顺便说一句,Lucence/Solr看起来也很有趣。谢谢。 – 2011-06-05 16:41:58

+1

你甚至可以用clojure使用Lucence/Solr。它是世界上最好的。 – 2011-06-05 16:53:00

-4
  1. 这取决于你的意思是巨大的。
  2. 字符串二郎是痛苦..

但:

如果庞大的手段几十分布的机器,比去使用Erlang写在文本友好语言工作者(蟒蛇?perl的?)。您将拥有高度并发的本地工作人员的顶层分布式层。每个工人将由erlang进程表示。如果您需要更多性能,请将您的工作人员改写为C.在Erlang中,与其他语言聊天非常容易。

如果巨大仍然意味着一个强大的机器与JVM。那不是那么庞大。

如果数以百计的机器数量巨大,我认为您需要在C++堆栈上更强大的Google-like(bigtable,map/reduce)。 Erlang仍然可以,但是你需要优秀的开发人员来编写代码。

+3

Erlang中的字符串很痛苦吗?我并不完全同意这一点。可能是因为你每次都必须做一些事情,或者因为它缺少尖端的python字符串操作。我已经完成了我在Python中需要的尽可能多的字符串处理。2.x – 2011-06-06 10:28:01

+0

我不介意写东西,但处理编码尤其突破。字符串也是一个列表,它被分配在堆上。它不会有效地使用内存,并且分析起来很复杂。 – user425720 2011-06-06 16:36:12

+2

使用二进制文件进行有效的字符串操作 – 2011-06-06 17:05:21

57

你真的是指并发或分布式吗?

如果你的意思是并发(多线程,多核心等),那么我会说Clojure是自然的解决方案。

  • Clojure的STM模型完全为多核并发设计,因为它非常高效地存储和管理线程之间的共享状态。如果你想了解更多,很值得看看this excellent video
  • Clojure STM允许并发线程安全地对数据进行变异。 Erlang通过使所有内容不可变来回避这个问题,这本身就很好,但当你真正需要共享可变状态时却无济于事。如果你想要在Erlang中共享可变状态,你必须通过一组既不高效也不方便的消息交互来实现它(这是一个没有共享模型的价格......)
  • 你会得到更好的性能Clojure如果你处于一个大型机器的并发环境中,因为Clojure不依赖消息传递,因此线程之间的通信可以更加高效。

如果你的意思是分布(即许多不同的机器共享了其有效运行的独立程序的网络工作),那么我会说二郎神是更自然的解决方案:

  • Erlang的不可变的,没什么共享消息传递风格迫使你以可分发的方式编写代码。因此,惯用的Erlang 自动可以分布在多台机器上并运行在分布式的容错设置中。
  • 因此Erlang非常适合这种用例,所以会是自然的选择,并且肯定会是最快的工作。 Clojure可以做到这一点,但你需要自己做更多的工作(也就是说,你需要实现或选择某种形式的分布式计算框架) - Clojure目前默认没有这样的框架。

从长远来看,我希望Clojure开发一个与Erlang相匹配的分布式计算框架 - 那么您可以拥有两全其美!

+9

并发性和并行性不是同一回事。 Erlang确实支持非常自然的并发性,并行方法也可以。 STM,消息传递,承诺和期货都是同时获得并发性和并行性的有效选项。你需要哪一个是由你想解决的问题的性质决定的。 – 2011-06-17 11:57:44

+2

在erlang中,ETS表可用于共享可变状态。 – jtmoulia 2013-06-13 22:28:37

+3

不要忘记Erlang的per-process GC - 即使Clojure“开发了分布式计算框架”,JVM的GC也不会与Erlang的GC相匹配。 – 2016-03-27 17:08:00

0

我的方法是在每种语言中编写一个简单的测试并测试每个语言的性能。这两种语言都与C风格的语言有些不同,如果你不习惯它们(并且你没有一个习惯于它们的团队),你最终可能会面临维护的噩梦。

我也会看看使用Groovy 1.8之类的东西。 Groovy现在包含GPars以支持并行计算。 Groovy中的字符串和文件操作确实很容易。