Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Erlang在所有这些小型数学基准上都比Java慢?_Java_Performance_Erlang_Compare - Fatal编程技术网

为什么Erlang在所有这些小型数学基准上都比Java慢?

为什么Erlang在所有这些小型数学基准上都比Java慢?,java,performance,erlang,compare,Java,Performance,Erlang,Compare,在考虑分布式/并发/故障切换/可伸缩后端环境的Java替代方案时,我发现了Erlang。我花了一些时间在书籍和文章上,几乎所有人(甚至是Java上瘾的家伙)都说Erlang在这样的环境中是一个更好的选择,因为许多有用的东西都是现成的,不太容易出错 我确信Erlang在大多数情况下更快,这主要是因为不同的垃圾收集策略(每个进程)、缺少共享状态(b/w线程和进程)以及更紧凑的数据类型。但当我发现Erlang的速度慢了好几个数量级时,我非常惊讶,例如从x10到x100 即使在并发任务上,也可以在多个核

在考虑分布式/并发/故障切换/可伸缩后端环境的Java替代方案时,我发现了Erlang。我花了一些时间在书籍和文章上,几乎所有人(甚至是Java上瘾的家伙)都说Erlang在这样的环境中是一个更好的选择,因为许多有用的东西都是现成的,不太容易出错

我确信Erlang在大多数情况下更快,这主要是因为不同的垃圾收集策略(每个进程)、缺少共享状态(b/w线程和进程)以及更紧凑的数据类型。但当我发现Erlang的速度慢了好几个数量级时,我非常惊讶,例如从x10到x100

即使在并发任务上,也可以在多个核心和单个核心上执行

原因是什么?我想到了这些答案:

  • 在大多数任务上使用Java原语(=>无堆/gc)
  • Java代码和Erlang进程中的线程数相同,因此actor模型在这里没有优势
  • 或者说Java是静态类型的,而Erlang不是
  • 还有别的吗
如果这是因为这些都是非常具体的数学算法,有人能展示更多的真实/实践性能测试吗


更新:到目前为止,我已经得到了答案,总结说Erlang不是适合这种特定的“快速Java案例”的工具,但我不清楚的是——Erlang效率低下的主要原因是什么:动态类型,GC或糟糕的本机编译?

基准测试永远不适合说出他们真正测试的东西以外的任何东西。如果您觉得基准测试只是测试原语和经典线程模型,那么这就是您所了解的。现在,您可以有信心地说,Java在原语的数学上比Erlang更快,对于这些类型的问题,它也是经典的线程模型。您对大量线程的性能或更复杂的问题一无所知,因为基准测试没有测试这一点

如果您正在进行基准测试所测试的数学类型,那么请使用Java,因为它显然是适合这项工作的正确工具。如果您想在几乎没有共享状态的情况下做一些高度可伸缩的事情,请为此找到一个基准,或者至少重新评估Erlang


如果你真的需要在Erlang做重数学,考虑使用HIPE(无论如何考虑它)。Erlang不是为数学而建的。它是在考虑通信、并行处理和可伸缩性的基础上构建的,因此,在数学任务中测试它有点像测试手提钻是否能给您带来令人耳目一新的按摩体验

这就是说,让我们稍微放松一下:

如果您想在JVM中使用Erlang风格的编程,请查看or。

我对Erlang一无所知,但无论如何,这似乎是一种比较苹果和桔子的方法。您必须知道,在十多年的时间里,我们花费了大量的精力来改进java性能,使之达到今天的水平


(对我来说)志愿者或小公司所做的语言实现无法超过这一努力并不令人惊讶。

正如其他答案所指出的那样,Erlang旨在有效解决现实生活中的问题,这与基准问题有点相反

但我想再说明一个方面——erlang代码的简洁性(在某些情况下意味着开发的快速性),这在比较基准测试实现之后很容易得出结论

例如,k-核苷酸基准:
Erlang版本:
Java版本:


如果您想要更多的真实基准测试,我建议您

erlang必须为每个值分配内存这一事实,而在java中,如果您希望它更快,通常会重用变量,这意味着对于“紧循环”基准测试,它总是更快

使用-client标志和装箱原语对java版本进行基准测试并将其与erlang进行比较是很有趣的


我认为使用hipe是不公平的,因为它不是一个活跃的项目。我想知道是否有任何任务关键型软件正在运行。

Erlang解决方案使用ETS,即Erlang术语存储,它就像在单独进程中运行的内存中数据库。由于它位于一个单独的进程中,因此与该进程之间的所有消息都必须序列化/反序列化。我认为,这将解释很多缓慢的现象。例如,如果你看一下“regex dna”基准测试,Erlang只比Java稍慢一点,而且它不使用ETS。

我对此很感兴趣,因为有些基准测试非常适合Erlang,比如基因测序。因此,我做的第一件事是研究C和Erlang的反向补码实现,以及测试细节。我发现这个测试是有偏差的,因为它没有考虑erlang启动VM所需的时间,而调度程序、本机编译的C启动速度要快得多。这些基准的衡量方式基本上是:

时间erl-noshell-s revcomp5 main

现在,基准测试显示Java花了1.4秒,erlang/w HiPE花了11秒。运行(单线程)Erlang代码花费了我0.15秒,如果你不考虑启动vm所花费的时间,实际工作负载只需要3000微秒(0.003秒)

因此,我不知道这是如何进行基准测试的,如果执行100次,那么就没有意义了,因为启动erlang VM的成本将是x100。如果输入的时间比给定的时间长得多,这是有意义的,但我在该网站的网页上看不到详细信息。为了使托管语言的基准测试更加公平,让代码(Erlang/Java)向python(进行基准测试的python)发送一个Unix信号,使其命中启动函数

现在撇开基准测试不谈,ErlangVM实际上只是在最后执行机器代码,就像Java VM一样。因此,在Erlang中,数学运算不可能花费更长的时间