groovy安装配置及其开启indy、@CompileStatic
前提
目前groovy最新版本4.0.1,但该版本没有indy,故改用3.0.10
环境:win10
groovy安装
地址:https://mirrors.cloud.tencent.com/apache/groovy/3.0.10/distribution/apache-groovy-sdk-3.0.10.zip
安装目录:D:\YDGreenNew\groovy-3.0.10
环境变量:
GROOVY_HOME=D:\YDGreenNew\groovy-3.0.10
Path后面加上%GROOVY_HOME%\bin
验证:
cmd命令行敲入groovy -v会输出版本号信息
indy版本切换
1)移除%GROOVY_HOME%\lib\groovy-*.jar(一共有好几个)
2) 将%GROOVY_HOME%\indy\下的jar名称去掉-indy,并复制到上门的lib目录
3) 验证: groovy -v
java、非indy、indy、@CompileStatic四种方式的字节码比较
知识点
Indy
指的是invokedynamic字节码指令(在jdk1.8中lambda表达式会使用到),groovy中使用该指令,使得动态语言实现更加方便高效。
官网见https://groovy-lang.org/indy.html
@CompileStatic优化
如官网https://groovy-lang.org/differences.html#primitive-optimisation-numbers所示
使用@CompileStatic可以生成更少的字节码,表达式使用的字节码,java也会使用,因此可以估计执行效率上和java程序相差不大了
四种方式class比较
附录中ExampleJava.java、ExampleNormal.groovy及ExampleIndy.groovy、ExampleCompileStatic.groovy进行编译:
D:\workspaceGroovy>javac ExampleJava.java
D:\workspaceGroovy>groovy --indy ExampleIndy.groovy
hello world
D:\workspaceGroovy>groovyc --indy ExampleIndy.groovy
D:\workspaceGroovy>groovyc ExampleNormal.groovy
D:\workspaceGroovy>groovyc ExampleCompileStatic.groovy
idea打开ExampleIndy.class及ExampleNormal.class(class见附录)。主要区别如下:
可看到indy方式使用到了invokedynamic,字节码更加简洁;
而ExampleIndy.class和ExampleCompileStatic.class区别如下:
可以看到@CompileStatic的方式更加简洁,println方法直接调用,并不会使用invokedynamic字节码指令;
总结
1.因此针对例子,执行效率 java > @CompileStatic > indy > 普通的groovy代码
2.其实在更多的测试中,针对cpu密集型的代码,@CompileStatic比较接近java了,而indy和非indy的代码效率差不多,是java的几倍,故耗cpu型的groovy开启@CompileStatic效果会更好;
3.在IO和内存密集型的代码在测试时,并没有发现特别明显的区别,正常的groovy脚本即可;
4.改安装4.0.1版本(最新版本)
D:\workspaceGroovy>groovy -v
Groovy Version: 4.0.1 JVM: 1.8.0_171 Vendor: Oracle Corporation OS: Windows 10
D:\workspaceGroovy>groovyc ExampleNormal.groovy
可以发现ExampleNormal.class和ExampleIndy.class完全一致了,即最新版本下,indy默认开启了!
其它:
1.maven引入示例:
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>3.0.10</version>
<classifier>indy</classifier>
</dependency>
<dependency>
<groupId>org.apache.groovy</groupId>
<artifactId>groovy</artifactId>
<version>4.0.1</version>
</dependency>
附录-代码
待比较的类及class反编译后类
ExampleJava.java
class ExampleJava {
public static void main(String[] args) {
System.out.println("hello world");
}
}
ExampleNormal.groovy
class ExampleNormal {
static main(String[] args) {
println("hello world")
}
}
ExampleIndy.groovy
class ExampleIndy {
static main(String[] args) {
println("hello world")
}
}
ExampleCompileStatic.groovy
import groovy.transform.CompileStatic
@CompileStatic
class ExampleCompileStatic {
static main(String[] args) {
println("hello world");
}
}
ExampleJava.class
class ExampleJava {
ExampleJava() {
}
public static void main(String[] var0) {
System.out.println("hello world");
}
}
ExampleIndy.class
import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import groovy.transform.Generated;
import groovy.transform.Internal;
import java.beans.Transient;
public class ExampleIndy implements GroovyObject {
@Generated
public ExampleIndy() {
MetaClass var1 = this.$getStaticMetaClass();
this.metaClass = var1;
}
public static Object main(String... args) {
return ExampleIndy.class.invoke<invokedynamic>(ExampleIndy.class, "hello world");
}
@Generated
@Internal
@Transient
public MetaClass getMetaClass() {
MetaClass var10000 = this.metaClass;
if (var10000 != null) {
return var10000;
} else {
this.metaClass = this.$getStaticMetaClass();
return this.metaClass;
}
}
@Generated
@Internal
public void setMetaClass(MetaClass var1) {
this.metaClass = var1;
}
}
ExampleNormal.class
import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import groovy.transform.Generated;
import groovy.transform.Internal;
import java.beans.Transient;
import org.codehaus.groovy.runtime.callsite.CallSite;
public class ExampleNormal implements GroovyObject {
@Generated
public ExampleNormal() {
CallSite[] var1 = $getCallSiteArray();
super();
MetaClass var2 = this.$getStaticMetaClass();
this.metaClass = var2;
}
public static Object main(String... args) {
CallSite[] var1 = $getCallSiteArray();
return var1[0].callStatic(ExampleNormal.class, "hello world");
}
@Generated
@Internal
@Transient
public MetaClass getMetaClass() {
MetaClass var10000 = this.metaClass;
if (var10000 != null) {
return var10000;
} else {
this.metaClass = this.$getStaticMetaClass();
return this.metaClass;
}
}
@Generated
@Internal
public void setMetaClass(MetaClass var1) {
this.metaClass = var1;
}
}
ExampleCompileStatic.class
import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import groovy.transform.Generated;
import groovy.transform.Internal;
import java.beans.Transient;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
public class ExampleCompileStatic implements GroovyObject {
@Generated
public ExampleCompileStatic() {
MetaClass var1 = this.$getStaticMetaClass();
this.metaClass = var1;
}
public static Object main(String... args) {
DefaultGroovyMethods.println(ExampleCompileStatic.class, "hello world");
return null;
}
@Generated
@Internal
@Transient
public MetaClass getMetaClass() {
MetaClass var10000 = this.metaClass;
if (var10000 != null) {
return var10000;
} else {
this.metaClass = this.$getStaticMetaClass();
return this.metaClass;
}
}
@Generated
@Internal
public void setMetaClass(MetaClass var1) {
this.metaClass = var1;
}
}