Groovy 学习笔记3 运行效率

前端之家收集整理的这篇文章主要介绍了Groovy 学习笔记3 运行效率前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

第一篇笔记里面,我说groovy运行的居然还满快的,其实是个误会了。我上次做八皇后还是在8080上面用basic做的,和现在奔四上面的groovy相比是没有意义的。特地又做了个对比试验:@H_301_7@

 @H_301_7@

 1

@H_301_7@int  q = 9
 2

@H_301_7@ int [] i = new   int [q]
 3

@H_301_7@ int  count = 0
 4

@H_301_7@ long  t  =  System.currentTimeMillis();
 5

@H_301_7@scan( 0 )
 6

@H_301_7@println( " totle results: " + count)
 7

@H_301_7@println( " totle time: " + (System.currentTimeMillis() - t));
 8

@H_301_7@

@H_301_7@def scan(n)

@H_301_7@ {
 9

@H_301_7@

@H_301_7@    if (n==q)

@H_301_7@{
10

@H_301_7@        println(i.toList())
11

@H_301_7@        count++
12

@H_301_7@        return
13

@H_301_7@    }
14

@H_301_7@    i[n]=0
15

@H_301_7@

@H_301_7@    while(i[n]<q)

@H_301_7@{
16

@H_301_7@        i[n] = i[n]+1
17

@H_301_7@        if (check(n))
18

@H_301_7@            scan(n+1)
19

@H_301_7@    }
20

@H_301_7@}
21

@H_301_7@

@H_301_7@def check(n)

@H_301_7@ {
22

@H_301_7@    if (n>0)
23

@H_301_7@        for (j in 0..<n) 
24

@H_301_7@            if (i[j]==i[n] || i[j]-i[n]==j-|| i[j]-i[n]==n-j )
25

@H_301_7@                return false
26

@H_301_7@    return true
27

@H_301_7@}


运行结果是:totle time:7271 (为了用groovy控制台运行的,直接用groovy命令运行还要慢一点)@H_301_7@

java呢?@H_301_7@

queens.java:@H_301_7@

 @H_301_7@

 1

@H_301_7@

@H_301_7@public   class  queens 

@H_301_7@ {
 2

@H_301_7@    static int q=9;
 3

@H_301_7@    static int[] i=new int[q];
 4

@H_301_7@    static int count=0;
 5

@H_301_7@

@H_301_7@    public static void main(String[] args)

@H_301_7@{
 6

@H_301_7@        long t = System.currentTimeMillis();
 7

@H_301_7@        scan(0);
 8

@H_301_7@        System.out.println("totle results:"+count);
 9

@H_301_7@        System.out.println("totle time:"+(System.currentTimeMillis()-t));
10

@H_301_7@    }
11

@H_301_7@

@H_301_7@    private static void scan(int n)

@H_301_7@{
12

@H_301_7@

@H_301_7@        if (n==q)

@H_301_7@{
13

@H_301_7@            for (int k=0;k<q;k++) System.out.print(i[k]+(k==q-1?"/n":","));
14

@H_301_7@            count++;
15

@H_301_7@            return;
16

@H_301_7@        }
17

@H_301_7@        i[n]=0;
18

@H_301_7@

@H_301_7@        while(i[n]<q)

@H_301_7@{
19

@H_301_7@            i[n] = i[n]+1;
20

@H_301_7@

@H_301_7@            if (check(n))

@H_301_7@{
21

@H_301_7@                scan(n+1);
22

@H_301_7@            }
23

@H_301_7@        }
24

@H_301_7@    }
25

@H_301_7@

@H_301_7@    private static boolean check(int n)

@H_301_7@{
26

@H_301_7@

@H_301_7@        for(int j=0;j<n;j++)

@H_301_7@{
27

@H_301_7@

@H_301_7@            if (i[j]==i[n] || i[j]-i[n]==j-|| i[j]-i[n]==n-j )

@H_301_7@{
28

@H_301_7@                return false;
29

@H_301_7@            }
30

@H_301_7@        }
31

@H_301_7@        return true;
32

@H_301_7@    }
33

@H_301_7@}
34

@H_301_7@

@H_301_7@

运行结果是:totle time:271
@H_301_7@




每次运行花费的时间略有不同,groovy和java的运行速度看来大致相差10~30倍左右。
@H_301_7@


能说这是脚本语言天生的缺陷吗?我们来看看同样是类似java语法的脚本语言javascript在IE里面的速度:
@H_301_7@

@H_301_7@

 1

@H_301_7@var q = 9  
 2

@H_301_7@var i = [] 
 3

@H_301_7@var count = 0  
 4

@H_301_7@var d  =   new  Date(); 
 5

@H_301_7@scan( 0
 6

@H_301_7@document.write( " totle results: " + count + " <br> "
 7

@H_301_7@document.write( " time used: " + ( new  Date() - d) + " <br> "
 8

@H_301_7@
 9

@H_301_7@

@H_301_7@function scan(n)

@H_301_7@
10

@H_301_7@

@H_301_7@    if (n==q)

@H_301_7@
11

@H_301_7@        document.write(i+"<br>"
12

@H_301_7@        count++ 
13

@H_301_7@        return 
14

@H_301_7@    } 
15

@H_301_7@    i[n]=0 
16

@H_301_7@

@H_301_7@    while(i[n]<q)

@H_301_7@{
17

@H_301_7@        i[n] = i[n]+1 
18

@H_301_7@

@H_301_7@        if (check(n))

@H_301_7@{
19

@H_301_7@            scan(n+1
20

@H_301_7@        } 
21

@H_301_7@    } 
22

@H_301_7@}  
23

@H_301_7@
24

@H_301_7@

@H_301_7@function check(n)

@H_301_7@
25

@H_301_7@    for (var j=0; j<n;j++)
26

@H_301_7@        if (i[j]==i[n] || i[j]-i[n]==j-|| i[j]-i[n]==n-j )
27

@H_301_7@            return false  
28

@H_301_7@    return true 
29

@H_301_7@}  






运行结果是: time used:1241
比groovy快了5倍以上。groovy可真是够慢的。
@H_301_7@


把groovy编译的class文件反编译了一下,看到groovy生成代码效率确实是太低了,我们就看循环最内层的check函数吧:
@H_301_7@


@H_301_7@

1

@H_301_7@

@H_301_7@def check(n)

@H_301_7@ {
2

@H_301_7@    if (n>0)
3

@H_301_7@        for (j in 0..<n) 
4

@H_301_7@            if (i[j]==i[n] || i[j]-i[n]==j-|| i[j]-i[n]==n-j )
5

@H_301_7@                return false
6

@H_301_7@    return true
7

@H_301_7@}


 @H_301_7@


编译后变成



@H_301_7@

 1

@H_301_7@     public  Object check(Object obj)
 2

@H_301_7@

@H_301_7@    

@H_301_7@ {
 3

@H_301_7@        if(ScriptBytecodeAdapter.compareGreaterThan(obj, new Integer(0)))
 4

@H_301_7@

@H_301_7@        

@H_301_7@{
 5

@H_301_7@            Object obj1 = null;
 6

@H_301_7@            for(Iterator iterator = ScriptBytecodeAdapter.asIterator(ScriptBytecodeAdapter.createRange(new Integer(0), obj, false)); iterator.hasNext();)
 7

@H_301_7@

@H_301_7@            

@H_301_7@{
 8

@H_301_7@                Object obj2 = iterator.next();
 9

@H_301_7@                Object obj3 = null;
10

@H_301_7@

@H_301_7@                if(ScriptBytecodeAdapter.asBool(ScriptBytecodeAdapter.asBool(ScriptBytecodeAdapter.compareEqual(ScriptBytecodeAdapter.invokeMethod(ScriptBytecodeAdapter.getGroovyObjectProperty(this"i"), "getAt", ((Object) (new Object[] 

@H_301_7@{
11

@H_301_7@    obj2
12

@H_301_7@

@H_301_7@}))), ScriptBytecodeAdapter.invokeMethod(ScriptBytecodeAdapter.getGroovyObjectProperty(this, ((Object) (new Object[] 

@H_301_7@{
13

@H_301_7@    obj
14

@H_301_7@

@H_301_7@})))) || ScriptBytecodeAdapter.compareEqual(ScriptBytecodeAdapter.invokeMethod(ScriptBytecodeAdapter.invokeMethod(ScriptBytecodeAdapter.getGroovyObjectProperty(this, ((Object) (new Object[] 

@H_301_7@{
15

@H_301_7@    obj2
16

@H_301_7@

@H_301_7@}))), "minus", ((Object) (new Object[] 

@H_301_7@{
17

@H_301_7@

@H_301_7@    ScriptBytecodeAdapter.invokeMethod(ScriptBytecodeAdapter.getGroovyObjectProperty(this, ((Object) (new Object[] 

@H_301_7@{
18

@H_301_7@        obj
19

@H_301_7@    })))
20

@H_301_7@

@H_301_7@}))), ScriptBytecodeAdapter.invokeMethod(obj2, ((Object) (new Object[] 

@H_301_7@{
21

@H_301_7@    obj
22

@H_301_7@

@H_301_7@})))) ? ((Object) (Boolean.TRUE)) : ((Object) (Boolean.FALSE))) || ScriptBytecodeAdapter.compareEqual(ScriptBytecodeAdapter.invokeMethod(ScriptBytecodeAdapter.invokeMethod(ScriptBytecodeAdapter.getGroovyObjectProperty(this, ((Object) (new Object[] 

@H_301_7@{
23

@H_301_7@    obj2
24

@H_301_7@

@H_301_7@}))), ((Object) (new Object[] 

@H_301_7@@H_731_2404@{
25

@H_301_7@

@H_301_7@    ScriptBytecodeAdapter.invokeMethod(ScriptBytecodeAdapter.getGroovyObjectProperty(this, ((Object) (new Object[] 

@H_301_7@{
26

@H_301_7@        obj
27

@H_301_7@    })))
28

@H_301_7@

@H_301_7@}))), ScriptBytecodeAdapter.invokeMethod(obj, ((Object) (new Object[] 

@H_301_7@{
29

@H_301_7@    obj2
30

@H_301_7@})))) ? ((Object) (Boolean.TRUE)) : ((Object) (Boolean.FALSE))))
31

@H_301_7@                    return Boolean.FALSE;
32

@H_301_7@            }
33

@H_301_7@
34

@H_301_7@        }
35

@H_301_7@        return Boolean.TRUE;
36

@H_301_7@    }
37

@H_301_7@




 @H_301_7@

一切都是object,做任何事情都是invokeMethod,两个整数的比较居然要写将近400个字符的代码,光看代码量都可以吓倒我了。这是我们期待的脚本语言吗?


groovy可以嵌入到java代码里面,但是java代码可以嵌入到groovy里面吗?我觉得groovy有必要提供这样一种机制,在有必要的时候可以消除性能瓶颈。可是现在只看到groovy里面可以通过Scriptom(现在还是beta版)嵌入vbs、js脚本(包括使用WSH,FSO)或者调用InternetExplorer、Media Player、Word和Excel等windows组件。看来对消除性能瓶颈的帮助不大。@H_301_7@

猜你在找的Groovy相关文章