Groovy与Java相比的性能如何?

67

Groovy相对于Java的性能表现如何?


3
Groovy被编译成Java字节码并在JVM上执行,因此我不会期望有任何差异。 - David Victor
9
@David:那不是真的。不同的编译器比其他编译器更有效率。并非每种JVM语言都具有相同的运行速度。此外,Groovy是一种解释语言(尽管它可能有一个编译模式)。 - Peter C
1
问题不在于哪个编译器比另一个更有效?问题的假设是在只有语言不同的环境中 - 不是编译器/ JVM - 性能上的差异是什么。正如评论所述,我不会期望有任何显著的差异 - 但您正确地指出Groovy可以被解释或编译。 - David Victor
1
@David:在我开始搜索基准测试时,我才意识到它们的重要性。大多数静态类型的JVM语言速度相似,但动态类型的速度较慢。然而,当Java 7发布带有“invokedynamic”指令时,这可能会改变。 - Peter C
1
@David:我不确定哪些Groovy功能是瓶颈,但动态类型变量肯定比静态类型的慢。 - Peter C
显示剩余7条评论
8个回答

54

很明显,Groovy是编译到JVM的。但这与性能关系不大。

最重要的是,Groovy是一种动态语言。这意味着大多数时候,Groovy编译器对于调用方法或检索属性的对象类型几乎没有认知。这对性能有一个巨大的影响。可能会有成千上万个实现someFancyMethodName()的不同类,它们没有共同的基类。然而,调用obj.someFancyMethodName()必须选择正确的方法。这没有比在运行时基于某种反射来决定更好的方法了。事实上,因为这个原因,每次对方法的调用都会通过调用对象元类上的invokeMethod()进行分派。如果您的程序抛出一些恶心的异常,则在堆栈跟踪中非常明显。甚至更糟糕的是,Groovy中的任何类都可以选择在运行时提供给定名称的方法实现,即在运行时生成它们。 Grails魔法使用了相当数量的这种功能,这会使问题变得更加复杂。当方法重载进入时,另一个问题就出现了。由于类型知识非常有限,因此无法在编译时选择正确版本的方法。生成的代码必须查看提供的对象,并通过制作一系列if-else语句来选择最适合提供的调用的实现。大多数情况下,这是一个非常不平凡的过程,从未被设计为在运行时执行。然而,Groovy必须这样做,以保持与Java的互操作性。

所有这些都使Groovy变得相当缓慢。事实上,比大多数动态语言(例如Python)更慢,而且更占用内存。

也就是说,我同意使用Groovy的原因肯定不是性能。大多数情况下,您将只优化一小部分代码。如果性能是问题,您可以随时将这些特定部分重写为纯粹的Java,或者尝试Groovy ++。虽然我自己没有尝试过,但我在网上阅读到的结果似乎非常有前途。

Groovy 2.0 我没有运行过更新版本的经验。坦率地说,我不再是一个活跃的 Groovy 用户。然而,我预计上述大多数问题基本上都很难解决,并需要重大的科学突破。我有一些开发 HHVM(Facebook 创建的 PHP 虚拟机)的经验,其中有许多更简单的功能表现不佳。


5
当然,Groovy比Java慢,但你在第二和第三段中所说的大部分要么是错误的,要么已经过时。请记住,多年来Groovy已经有了很大的进步。 - Peter Niederwieser
10
实际上,Groovy 1.8非常快,几乎接近于Java和Scala。但是这个答案现在已经过时了。 - Wanderson Santos
10
不是这样的。你有没有读过Groovy 1.8的变更日志?它确实在方法分派领域做了一些改进,但这主要涉及原始类型。现在这肯定会加速斐波那契基准测试,但问题是,这绝不是典型的用例。到目前为止,还没有任何动态语言能够接近Java的水平。我怀疑Groovy即使增加了所有复杂性,也永远不会比Python更快。 - julx
4
在你上面所说的内容中,你有对也有错。是的,Groovy只对原始类型有那么快的速度,并不是普遍适用的。这是正确的。然而,每个方法调用都必须通过某种调用方法(invoke method)是不正确的。自1.6版本以来,Groovy在运行时使用生成的字节码存根进行调用站点缓存。这允许在没有反射的情况下进行方法调用。第一次调用通常仍然使用反射,因此你会看到它。 - blackdrag
1
目前看来,Groovy 2 在 Groovy 的动态部分方面将有很多提供。我这里有一个原型,可以使用 invokedynamic 以与当前使用基本优化相同的速度运行斐波那契示例。最大的区别是 invokedynamic 版本对元编程和缺失类型更加不可知。我还不确定这最终可能意味着什么,例如 Grails,但这看起来是非常快速的 Groovy 的一个非常好的基础。稍后可能需要对 Groovy 中的 MOP 进行一些更改以充分利用其潜力。 - blackdrag
显示剩余9条评论

23

现在是2012年,Groovy 2.0准备就绪...

"使用@CompileStatic,Groovy的性能比Java慢1-2倍,没有Groovy,则慢3-5倍。(...)这对我来说意味着Groovy可以用于需要与Java性能相当的应用程序."

性能测试:Groovy 2.0 vs. Java http://java.dzone.com/articles/groovy-20-performance-compared

除了作者之外,我自2008年以来一直成功地使用Groovy,不仅为简历,而是为了按时完成工作需求。性能始终取决于您想要做什么。


对于那些抱怨数字使用情况的人,这里有一个真实的使用案例,使用 web 框架: http://www.jtict.com/blog/rails-wicket-grails-play-lift-jsp/


"Groovy 1.8.x针对fib(42)的原型大约需要3.8秒(只比Java慢12%,比Groovy 1.0快100倍以上),所以我们不再鼓励人们在Java中编写此类“热点”代码."

来源:http://www.wiki.jvmlangsummit.com/images/0/04/Theodorou-Faster-Groovy-1.8.pdf

"我对Groovy在数值计算方面的性能提高感到印象深刻。 Groovy 1.8 在我的项目jlab (http://code.google.com/p/jlabgroovy/)中,有时可以胜过我的其他项目ScalaLab (http://code.google.com/p/scalalab) 的性能 !!"

来源:http://groovy.329449.n5.nabble.com/Great-improvements-in-Groovy-s-performance-for-numerical-computing-td4334768.html

Groovy在数值计算方面的性能得到了很大改善。对于那些需要进行科学计算或数据分析工作的开发人员,这是一个重要的进步。由于Groovy脚本使用Java底层库,因此它们可以与Java代码互操作,从而使Groovy成为一种很好的补充语言。


参见:http://docs.codehaus.org/display/GROOVY/Groovy+1.8+release+notes#Groovy1.8releasenotes-Performanceimprovements - David Victor
6
我认为这个回答是有误导性的。在涉及纯数值计算的一个特定领域中,Groovy仍然比其他语言慢12%。对于整体情况,我建议阅读@julkiewicz的回答。 - David Victor
2
@DavidVictor,你在谈论动态语言和静态类型的区别。只有12%?太棒了!你正在谈论具有MOP和AST的真正动态语言!随着Groovy 1.8的推出,它变得更加接近。现在只需查看Groovy 2.0... Groovy不仅在功能上领先于所有动态语言,而且是最快的动态(真正的动态)语言,不仅在JVM上,还在PHP、Python和其他动态语言中。最好的问候! - Wanderson Santos
2
在这种情况下,你使用@CompileStatic会导致很多限制和副作用,你可能不应该称其为Groovy。 - Καrτhικ
这绝对是销售推广的话术。实际上,六年后我告诉你@CompileStatic是一个无关紧要的功能。 - Lothar
显示剩余2条评论

12

Groovy提供了比Java更多的语法糖,但仍在JVM上运行,因此需要JVM进行一些额外的工作来提供这些语法糖。尽管如此,在绝大部分正常用途中,差异非常小。

此外,如果您恰好编写了一个在Groovy中运行太慢的函数,可以将其用Java编写并从您的Groovy代码中调用。这是团队推荐的解决方案,我可以证明其工作得很好而且很简单。

在我看来,对于我们大多数人所做的编程工作来说,这不是问题。


8

3

我认为,您需要查看这篇关于Groovy、Python、PHP和Ruby的科学比较。

http://blog.websitesframeworks.com/2013/11/comparison-of-programming-languages-ruby-groovy-python-and-php-353/

他们进行了一项练习,并在以下因素上对这些编程语言进行了比较:

Comparison of time developing each exercise

Comparison of readability of the languages

Comparison of results in benchmarks and lines of code. From the project Computer Language Benchmarks Game

Conclusions

这是一个很好的快速学习,可以帮助你确定哪种语言更好。


1
请在您的回答中添加一些来自链接的细节,谢谢! - maxshuty

2

一般来说,Groovy会比较慢。而使用Groovy++可以避免这个问题,它提供了大部分Groovy的功能,但是可以静态编译,并且性能与Java相当。


缓慢是相对的,而在Groovy 1.8中,你将不得不重新考虑它:http://regispires.wordpress.com/2010/10/23/comparacao-de-performance/ - Wanderson Santos
2
可能是这样。我是在一般性的讨论中说的。那是3月8日的事情。我不确定你为什么要链接到这篇博客文章。它看起来有点像西班牙语。 - Jochen Bedersdorfer

0

在开发AWS Lambdas时,Java比Groovy更快。除此之外,在所有其他情况下,您可能感受不到太大的差异。


-12

Groovy被编译成字节码.class文件,但运行Groovy类需要约5MB的Groovy库,这会导致性能开销。


1
仅仅5MB的Groovy库并不会造成性能开销,而是编译器为支持Groovy语法所需创建的指令数量最终导致了它的缓慢(也就是JVM在运行时需要执行的指令数量)。 - Dominik Dorn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接