扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
三年前,我在javaworld写了一遍叫做“Java Scripting语言,那种是适合你的?”的文章。当我收集解释器并进行比较时,我尽量选择那些看起来满足苛刻商务需求的。理想状态下,我希望解释器能够方便的扩展应用的用户接口,并且有易读的脚本代码,高可靠,快速,有好的支持和文档,并且是完备的。在那个时候,我把列表限制到了Jacl,Jython,Rhion和BeanShell。
过去的三年中发生了很多变化。可选项不再是很少的几个,不管是动态开发还是直接选择,可选的脚本语言都有一打以上。可靠的选择列表比三年前增多了,现在还包括了Groovy, JudoScript, Pnuts和BeanShell。我们还可以考虑不再这个列表中的其他解释器,但这个列表中,已经足够开发人员自己的所需了。
我准备标准化所有解释器,看看Jacl, Jython, Rhion和BeanShell在2002年后性能有没有提高,并看看Groovy, JudoScript, Jruby和Pnuts同它们比较起来会怎样。我认为,看看不同脚本语言有什么独特之处,有什么特别的强项和弱点是很有意思的事情。
商务风险
在以前的文章里,我讲述了一些著名的优秀脚本解释器的资料,并说明了结合脚本解释器时你可能遇到的风险。本文中,我把这些内容简化为一些要点,并根据我在写那些文章之后的经验进行了改进。Java脚本解释器的优点是毋庸置疑的。使用脚本语言编码比使用java简单;脚步语言使程序的应用逻辑和用户界面的推动(drive/驱动?)和扩展成为可能;脚本代码可以违反java应用中类接口而运行,这是非常强大的功能。这样可以容易的编写程序测试驱动(write test drivers against your program),与编码并编译用于java类的单元测试相比,这是更加快速的。另外,如果用户花时间使用脚本扩展你的应用,他们就作你的工具上进行了投资,这使得你在竞争中多了一件利器。
但是,当在应用中集成jiava脚本解释器时,你必须面对一定的风险。两个主要的风险是,解释器可能成为孤儿,或者是当你把产品装上后,你可能发现解释器的致命缺陷。大多数解释器是通过开源模型动态维护和更新的,在这种情况下,你可以向研究你所发现问题的专家寻求帮助,给解释器打补丁,或者在未来版本中包含你需要的bug-fix(bug修理?)。这是一种安全的赌博,但并不能得到足够保证。如果你正严肃的考虑采用某个特定的解释器,请先看看它的开发站点,看看它的代码的进化,看看上面的流言板,用户的提问都有答案否。这可以帮助你了解代码支持的实际情况。
自我保护的另一格措施是,对你准备采用的任脚本何解释器进行完全测试。一些解释器在发布时包含了一个单元测试集。在测试你的应用中集成的解释器时,这些单元测试可以作为你的更大的测试集中的一部分。在测试解释器和应用之间的集成时,可以剔出自己的工作(you have your work cut out for you),因为脚本解释器有足够的弹性,并向开发人员暴露了足够的功能。你在早期向质量保证投入时间,而不是在应用已经成为产品,当用户需要急切的bug修复时才考虑。
新的竞争者列表
如果你正在寻找一个脚本解释器,你有很多选择。一些解释器支持已经存在的语言,比如Ruby, Python, JavaScript, Java和Tcl。另外一些解释器,如JudoScript, Groovy和Pnuts,选择了它们自己的类似java的语言语法。在比较不同的解释器,需要进行的最大的选择是,那种脚本语言的语法能很好的适合你的应用。像这种个人偏好发生作用的技术选择,可能在不同的开发人员团队引起激烈的争论。也许本文能有助于解决一些争论。
我收集比较了最近发布的八种不同的脚本解释器。解释器及其版本都在下表中列出。如果你对这些解释器并不熟悉,我还给出了每种解释器功能和开发活动的概要(a thumbnail sketch)。
脚本语言 |
版本号 |
简短描述 |
Jacl |
|
Tcl解释器的java实现。如果你希望在脚本中使用工具包来创建用户接口类,看看Swank工程中的包裹(wrap)java swing 工具的类集。Jacl已经存在较长时间了,并且还在持续改进。 |
Jython |
2.1 |
Python解释器的java实现。我注意到的一个问题是,已经有很长一段时间没有看到这个解释器的新版本了。但在Jython的网站上,说明了改变这种现状的计划,并且有基金支持。 |
Rhino |
|
JavaScript解释器的java实现。它还支持把脚本编译成类文件。它的最新版本在几个月前发布,并加入了xml支持。 |
JRuby |
0.8 |
Ruby解释器的java实现。它正在发展中,其测试版0.8表现良好。 |
BeanShell |
2.0 beta 2 |
它是一个java源文件解释器,正在持续的发展和加入新特性。2.0版本提供了完全的普通java源文件解释支持。 |
Groovy |
1.0 beta 9 |
Groovy是把Python和Ruby的特征加入java类似语法形成的,由很多令人兴奋的特征。可以把脚本直接编译成类文件,对不同的IDE,又很多Groovy插件可供选择,JSR委员会正在制定Groovy的规范。 |
JudoScript |
0.9 |
它有和JavaScript类似的编程语法,学习和使用更加容易。在它的FAQ中提到了它的一个明确目标:“支持对象级,操作系统级和应用级的脚本”。我测试的0.9版运行良好。 |
Pnuts |
1.1 beta 2 |
Pnuts有和java相似的编程语法,并保持持续更新。它可以把脚本直接编译成java类文件。 |
第一个指标:性能
未来测试第一项指标,我为每个解释器编写了等价的脚本代码,让他们完成简单的任务集并记录它们执行脚本所花的时间。我的测试脚本主要关注基本操作,如循环,整数比较和大的一维、二维数组分配和初始化。用于各个解释器的测试脚本和运行它们的java程序可以在原文资源部分下载。
在基准测试中最有用的信息是,解释器完成简单任务速度的apples-to-apples比较。如果你重点考虑吞吐量,基准数将十分重要。对每种脚本语言,我尽力编写相识的测试代码。测试使用Java
1到1,000,000的计数
1,000,000次整数相等比较
分配并初始化包含100,000个元素的数组
分配并初始化一个500*500的二维数组
在2002年后有提高么?
在告诉你哪个解释器最快之前,我们先看看图1,这个条状图列出了很多耗时任务的结果:1百万次整数相等比较。对2002年文章中讲述的4种脚本解释器,我给出了在Java
四项任务的总时间
由于解释器在速度方面都十分相似(至少对我的基准测试是这样),我把各解释器完成四项基准测试所耗的总时间算出来并在图2中给出。
多变的标志
对这些简单测试,Rhino,Pnuts和Jytho始终是最快的,紧跟在后面的时Groovy,然后是JudoScript,然后是其他的。这些性能参数对你是否有用,取决于你希望脚本语言做的事情。如果你的脚本函数包含大量的迭代,并且用户要等待结果,你就需要关注速度最快的解释器,或者你就该考虑用java实现高性能要求的算法,而不是脚本代码。如果你的脚本只需要很少的重复操作,这些解释器速度的差异就不是那么重要了,快速的硬件也会使问题变得不同。
还有一点需要指出的是,即使最快的解释器,完成上面测试所用的时间也是同样功能java代码所用时间的大约40倍。如果速度是你最主要的问题,你必须清楚,最有意义的事情是用java代替脚本代码实现关键算法。
一些脚本解释器支持脚本代码直接编译成字节码。我对这将会产生多大的性能差异非常好奇,所以我进行了另一项测试。我用Rhino脚本解释器把基准测试脚本编译成了字节码,然后我把整个基准测试集用脚本和脚本产生的字节码分别运行了10遍。令人惊奇的是,与直接运行脚本相比,脚本码编译成字节码再运行仅仅节省了10%的时间。我最初任务,JVM的魔咒占用了运行测试集的大部分时间,但进一步的检查发现JVM魔咒本身只占测试集运行总时间的20%。简单脚本代码编译成字节码看起来会有积极的意义,但这并不一定是显著提高性能的银弹。也许在更长的或者,更加计算中心的脚本中,会看到不同的结果。
第二个标准:集成难度
第三个标准:许可证
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者