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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值