yet*_*der 34 java erlang performance compare
在考虑用于分布式/并发/故障转移/可扩展后端环境的Java替代方案时,我发现了Erlang.我花了一些时间在书籍和文章上,其中几乎所有人(甚至是Java上瘾的人)都说Erlang在这样的环境中是更好的选择,因为许多有用的东西都是以不易出错的方式开箱即用的.
我确信Erlang在大多数情况下更快,主要是因为不同的垃圾收集策略(每个进程),缺少共享状态(黑白线程和进程)和更紧凑的数据类型.但是当我发现Erlang与Java数学样本的比较时,我感到非常惊讶,其中Erlang的速度慢了几个,例如从x10到x100.
即使是并发任务,也可以在几个核心和一个核心上完成.
这是什么原因?想到这些答案:
如果那是因为这些是非常具体的数学算法,那么任何人都可以展示更多真实/实践性能测试吗?
更新:到目前为止,我已经得到了答案,总结了Erlang不是这种特定"快速Java案例"的正确工具,但我不清楚这一点 - 这里Erlang效率低下的主要原因是什么:动态类型,GC还是可怜的原生编译?
Emi*_*röm 14
除了他们真正测试的东西之外,基准测试对于说其他任何东西都不好.如果您认为基准测试只是测试基元和经典线程模型,那么您就可以获得相关知识.你现在可以有信心地说,Java在基元数学方面比Erlang更快,而且对于那些类型的问题也是经典的线程模型.您对大量线程的性能或更多涉及的问题一无所知,因为基准测试没有对此进行测试.
如果您正在使用基准测试的数学类型,请使用Java,因为它显然是该工作的正确工具.如果你想做一些可扩展的东西,几乎没有共享状态,找到一个基准或者至少重新评估Erlang.
如果你真的需要在Erlang中做大量的数学运算,可以考虑使用HiPE(无论如何都要考虑它).
正如其他答案所指出的那样 - Erlang旨在有效地解决现实生活中的问题,这与基准问题有点相反.
但是我想启发另一个方面 - 在比较基准测试实现之后,可以很容易地得出erlang代码的简洁性(在某些情况下意味着开发的快速性).
例如,k-核苷酸基准:
Erlang版本:http
://benchmarksgame.alioth.debian.org/u64q/program.php?test = knucleotide&lang = hipe&id = 3 Java版本:http://benchmarksgame.alioth.debian.org /u64q/program.php?test=knucleotide&lang=java&id=3
如果你想要更多真实的基准测试,我建议你比较C++和Erlang For Motorola Telecoms Software
我对此感兴趣,因为一些基准测试非常适合erlang,例如基因测序.所以在http://benchmarksgame.alioth.debian.org/上我做的第一件事就是查看反向补码实现,包括C和Erlang,以及测试细节.我发现测试是有偏见的,因为它不会减少erlang启动VM/w调度程序所需的时间,本机编译的C启动速度要快得多.这些基准测量的方式基本上是:
time erl -noshell -s revcomp5 main < revcomp-input.txt
现在基准测试说Java花了1.4秒,而erlang/w HiPE花了11秒.运行(单线程)Erlang代码花了我0.15秒,如果你打算花费时间来启动vm,实际工作量只花了3000微秒( 0.003秒).
所以我不知道它是如何进行基准测试的,如果它完成100次则没有意义,因为启动erlang VM的成本将是x100.如果输入比给定的时间长很多,那就有意义,但我在网页上看不到任何细节.为了使托管语言的基准更加公平,让代码(Erlang/Java)向Python发送一个Unix信号(即进行基准测试),它会触发启动函数.
现在基准测试,erlang VM基本上只是在最后执行机器代码,以及Java VM.因此,在Erlang中,数学运算不会比在Java中花费更长的时间.
Erlang擅长的是需要经常变异的数据.如链式块密码.假设您有字符"0123456789",现在您的加密xors前两个字符乘以7,然后xors接下来的两个字符由前两个字符的结果添加,然后xors前两个字符减去当前2的结果,然后xors接下来的4个字符..等等
因为Erlang中的对象是不可变的,这意味着每次变异时都需要复制整个char数组.这就是为什么erlang支持称为NIFS的东西,这是你可以调用的C代码来解决这个问题.事实上,Erlang附带的所有加密(ssl,aes,blowfish ..)和压缩(zlib,..)都是用C实现的,从Erlang调用C也有近0的成本.
因此,使用Erlang可以获得两全其美的效果,您可以通过Erlang的并行性获得C的速度.
如果我以尽可能快的方式实现反向补码,我会使用C编写变异代码,但使用Erlang编写并行代码.假设无限输入,我会让Erlang拆分>
<<Line/binary, ">", Rest/binary>> = read_stream
通过循环将块发送到第一个可用的调度程序,循环由无限的EC2专用网络隐藏节点组成,每毫秒实时添加到集群.
那些节点然后通过NIFS调用C进行处理(C是对于alioth网站反向补充的最快实现),然后将输出发送回节点主机以发送到计算机.
要在Erlang中实现所有这些,我必须编写代码,就像我编写单线程程序一样,创建此代码需要一天时间.
要在Java中实现这一点,我将不得不编写单线程代码,我将不得不考虑从Managed到Unmanaged调用的性能(因为我们将使用C实现显然是为了grunt工作),然后重写为支持64核心.然后重写它以支持多个CPUS.然后再次重写它以支持群集.然后再次重写它以修复内存问题.
简而言之就是Erlang.