Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.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
为什么clojure在alioth基准测试中的表现比scala差_Scala_Clojure_Performance - Fatal编程技术网

为什么clojure在alioth基准测试中的表现比scala差

为什么clojure在alioth基准测试中的表现比scala差,scala,clojure,performance,Scala,Clojure,Performance,看 Clojure比java-server慢得多,而scala则不然 有什么好处 ref:Clojure是一种动态语言,它必须进行大量额外的运行时检查 编辑,现在不那么轻率了:不看基准测试的实际Clojure实现,性能差异也可能归因于这样一个事实,即惯用Clojure代码避免可变状态,并且,在其他条件相同的情况下,使用可变状态的算法通常比不使用可变状态的算法表现更好 给定的程序员是否能够正确地编写使用可变状态的代码是另一个问题,当然纯函数代码的声明性本质意味着许多优化至少在理论上是可能的。Sca

看 Clojure比java-server慢得多,而scala则不然

有什么好处


ref:

Clojure是一种动态语言,它必须进行大量额外的运行时检查

编辑,现在不那么轻率了:不看基准测试的实际Clojure实现,性能差异也可能归因于这样一个事实,即惯用Clojure代码避免可变状态,并且,在其他条件相同的情况下,使用可变状态的算法通常比不使用可变状态的算法表现更好


给定的程序员是否能够正确地编写使用可变状态的代码是另一个问题,当然纯函数代码的声明性本质意味着许多优化至少在理论上是可能的。

Scala功能通常是一点一点地引入的,并且在大多数情况下指定相应的Java代码。这将Scala转化为Java的一种进化,这种进化考虑到了新特性和性能之间的平衡


另一方面,Clojure在设计时考虑了一种非常不同的编程方法,并且具有与Java互操作的特性。但是,两种语言之间的阻抗不匹配(JVM是为Java准备的),可能会使Clojure的速度稍慢一些。对于某些问题,Clojure可能更快(例如使用不可变集合),但对于大多数应用程序可能不是这样。

许多基准测试速度较慢,因为直到最近,Clojure还需要更多的工作和专家知识才能获得好的性能。这些基准主要针对1.2


Clojure1.3有很多改进,使编写性能代码变得更简单。即使如此,社区中也没有多少人熟悉如何提高Clojure代码的性能,因此,随着人们提交更好的版本,这将是一个渐进的过程。

您可以用任何语言编写快速或慢速代码:-)

基于对一些Clojure代码的快速检查,我认为性能差异的主要原因是Clojure基准代码尚未完全优化以使用可用的最快语言功能

例如,Clojure中的以下功能都非常酷,对于开发方便非常有用,但会产生一些运行时性能开销:

  • 惰性序列和列表
  • 使用反射的动态Java互操作性
  • 运行时函数组合/第一类函数
  • 多方法/动态调度
  • 在REPL上使用eval或进行动态编译
  • 大整数算法
如果您希望获得绝对的最高性能(代价是一些额外的复杂性),您可能希望重写代码以避免这些问题,并使用以下方法:

  • 静态类型暗示(避免反射)
  • 瞬变
  • 宏(用于编译时代码操作)
  • 协议
  • Java原语和数组
  • 循环/重复迭代

使用上述方法,我发现在Culjure 1.2中,可以很接近java的性能,例如,考虑下面的代码来做一百万个附加:

使用惰性序列和BigInteger算法的未优化Clojure。它很好,功能齐全,但速度不是特别快:

(reduce 
  (fn [acc val] (unchecked-int (unchecked-add (int acc) (int val)))) 
  (range 0 1000000))

=> "Elapsed time: 65.201243 msecs"
优化的Clojure带有原始算法和循环/重现:

(loop [acc (int 0) i (int 0)] 
  (if (>= i (int 1000000)) 
    acc 
    (recur (unchecked-add acc i) (unchecked-inc i)) ))

=> "Elapsed time: 0.691474 msecs"
Java代码,一个非常标准的迭代循环:

public static int addMillion() {
    int result=0;
    for (int i=0; i<1000000; i++) {
        result+=i;
    }
    return result;
}

=> "Elapsed time: 0.692081 msecs"
publicstaticintadd000000(){
int结果=0;
对于(int i=0;i“运行时间:0.692081毫秒”

p、 我在Clojure代码中使用了未经检查的add而不是+以匹配Java的整数溢出行为。

部分原因在于测试本身,即您必须编写代码(不管它是什么语言)执行与Java版本完全相同的实现步骤。哦,您有一种不同的、可能更快的方法用您的语言执行X?太糟糕了


当测试的基础是循环和数组攻击以及需要多个浮点代码块的一般命令式样式时,您将得到无意义的数字。

编写一些更快的版本看起来可能很有趣……

@dnolen:您是说clojure在运行时不执行类型检查?还是scala执行?@dnole这完全是错误的,因为_________;正确的答案是。如果你知道我们不知道的事情,请解释一下!是的,can vs.does。动态语言几十年来一直表现出色。如果你幸运的话,这是因为运行时正在观察你的代码实际运行并编译它(类似于今天的高性能JS引擎),但通常是通过让您添加类型注释。@Alex-但它能始终编译成等效(至少是后JIT编译)字节码吗?Java不仅仅是“发出调用”,它还实现了新颖的例程。@dnolen-通过“完全错误”您的意思是“必须做”应该是“默认做”?@Alex-当你没有时间阅读代码时,你的评论会停留在轻率的状态;-)[如果代码必须“以惯用性为代价”重写,你已经了解了惯用代码在该语言实现中的性能。]添加了“性能”标签,因为这是大多数类似问题的地方。Clojure还没有成熟-Clojure 1.0于2009年5月发布,Scala的第一个公开发布是在2003年。在大多数情况下,Clojure持久数据结构应该比相应的Java数据结构稍慢。但是,在并发的Culjule是为达到java的性能而设计的,但它仍然是一个正在进行中的工作。@亚历克斯:AHA,是的,和LISP一样,是为了实现汇编语言的性能……25年后,它仍然在PRO中工作。