Groovy 学习笔记3 运行效率

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

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

 

 1

int  q = 9
 2

int [] i = new   int [q]
 3

int  count = 0
 4

long  t  =  System.currentTimeMillis();
 5

scan(
0 )
 6

println(
" totle results: " + count)
 7

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

def scan(n)
{
 9

    
if (n==q){
10

        println(i.toList())
11

        count
++
12

        
return
13

    }

14

    i[n]
=0
15

    
while(i[n]<q){
16

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

        
if (check(n))
18

            scan(n
+1)
19

    }

20

}

21

def check(n)
{
22

    
if (n>0)
23

        
for (j in 0..<n) 
24

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

                
return false
26

    
return true
27

}


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

java呢?

queens.java:

 

 1

public   class  queens  {
 2

    
static int q=9;
 3

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

    
static int count=0;
 5

    
public static void main(String[] args){
 6

        
long t = System.currentTimeMillis();
 7

        scan(
0);
 8

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

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

    }

11

    
private static void scan(int n){
12

        
if (n==q){
13

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

            count
++;
15

            
return;
16

        }

17

        i[n]
=0;
18

        
while(i[n]<q){
19

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

            
if (check(n)){
21

                scan(n
+1);
22

            }

23

        }

24

    }

25

    
private static boolean check(int n){
26

        
for(int j=0;j<n;j++){
27

            
if (i[j]==i[n] || i[j]-i[n]==j-|| i[j]-i[n]==n-j ){
28

                
return false;
29

            }

30

        }

31

        
return true;
32

    }

33

}

34

运行结果是:totle time:271




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


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

 1

var q = 9  
 2

var i
= [] 
 3

var count
= 0  
 4

var d 
=   new  Date(); 
 5

scan(
0
 6

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

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


 9

function scan(n)

10

    
if (n==q)
11

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

        count
++ 
13

        
return 
14

    }
 
15

    i[n]
=0 
16

    
while(i[n]<q){
17

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

        
if (check(n)){
19

            scan(n
+1
20

        }
 
21

    }
 
22

}
 
23


24

function check(n)

25

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

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

            
return false  
28

    
return true 
29

}
 






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


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


1

def check(n) {
2

    
if (n>0)
3

        
for (j in 0..<n) 
4

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

                
return false
6

    
return true
7

}


 


编译后变成



 1

     public  Object check(Object obj)
 2

    
{
 3

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

        
{
 5

            Object obj1 
= null;
 6

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

            
{
 8

                Object obj2 
= iterator.next();
 9

                Object obj3 
= null;
10

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

    obj2
12

}
))), ScriptBytecodeAdapter.invokeMethod(ScriptBytecodeAdapter.getGroovyObjectProperty(this, ((Object) (new Object[] {
13

    obj
14

}
)))) || ScriptBytecodeAdapter.compareEqual(ScriptBytecodeAdapter.invokeMethod(ScriptBytecodeAdapter.invokeMethod(ScriptBytecodeAdapter.getGroovyObjectProperty(this, ((Object) (new Object[] {
15

    obj2
16

}
))), "minus", ((Object) (new Object[] {
17

    ScriptBytecodeAdapter.invokeMethod(ScriptBytecodeAdapter.getGroovyObjectProperty(
this, ((Object) (new Object[] {
18

        obj
19

    }
)))
20

}
))), ScriptBytecodeAdapter.invokeMethod(obj2, ((Object) (new Object[] {
21

    obj
22

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

    obj2
24

}
))), ((Object) (new Object[] @H_453_2404@{
25

    ScriptBytecodeAdapter.invokeMethod(ScriptBytecodeAdapter.getGroovyObjectProperty(
this, ((Object) (new Object[] {
26

        obj
27

    }
)))
28

}
))), ScriptBytecodeAdapter.invokeMethod(obj, ((Object) (new Object[] {
29

    obj2
30

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

                    
return Boolean.FALSE;
32

            }

33


34

        }

35

        
return Boolean.TRUE;
36

    }

37




 

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


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

猜你在找的Groovy相关文章