Groovy 学习笔记3 运行效率

原创 2005年05月17日 13:54:00

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

 

 1int q=9
 2int[] i=new int[q]
 3int count=0
 4long t = System.currentTimeMillis();
 5scan(0)
 6println("totle results:"+count)
 7println("totle time:"+(System.currentTimeMillis()-t));
 8def 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}

21def 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:

 

 1public 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里面的速度:

 1var q=9 
 2var i=[] 
 3var count=0 
 4var d = new Date(); 
 5scan(0
 6document.write("totle results:"+count+"<br>"
 7document.write("time used:"+(new Date()-d)+"<br>"
 8
 9function 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
24function 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函数吧:


1def 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"i"), "getAt", ((Object) (new Object[] {
13    obj
14}
)))) || ScriptBytecodeAdapter.compareEqual(ScriptBytecodeAdapter.invokeMethod(ScriptBytecodeAdapter.invokeMethod(ScriptBytecodeAdapter.getGroovyObjectProperty(this"i"), "getAt", ((Object) (new Object[] {
15    obj2
16}
))), "minus", ((Object) (new Object[] {
17    ScriptBytecodeAdapter.invokeMethod(ScriptBytecodeAdapter.getGroovyObjectProperty(this"i"), "getAt", ((Object) (new Object[] {
18        obj
19    }
)))
20}
))), ScriptBytecodeAdapter.invokeMethod(obj2, "minus", ((Object) (new Object[] {
21    obj
22}
)))) ? ((Object) (Boolean.TRUE)) : ((Object) (Boolean.FALSE))) || ScriptBytecodeAdapter.compareEqual(ScriptBytecodeAdapter.invokeMethod(ScriptBytecodeAdapter.invokeMethod(ScriptBytecodeAdapter.getGroovyObjectProperty(this"i"), "getAt", ((Object) (new Object[] {
23    obj2
24}
))), "minus", ((Object) (new Object[] {
25    ScriptBytecodeAdapter.invokeMethod(ScriptBytecodeAdapter.getGroovyObjectProperty(this"i"), "getAt", ((Object) (new Object[] {
26        obj
27    }
)))
28}
))), ScriptBytecodeAdapter.invokeMethod(obj, "minus", ((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组件。看来对消除性能瓶颈的帮助不大。

JVM中Groovy脚本并行运行性能优化

当JVM中运行的Groovy脚本存在大量并发时,如果按照默认的策略,每次运行都会重新编译脚本,调用类加载器进行类加载。不断重新编译脚本会增加JVM内存中的CodeCache和PermGen,引发内存效...
  • jhyxzsf
  • jhyxzsf
  • 2016年04月05日 14:16
  • 1851

flash学习之 利用stage.invalidate()方法和render事件提高as3程序的运行效率

AS3中的DisplayObject有一个render事件,他会在重绘DisplayList之前触发,这给我们提供了在重绘之前最后一次操作的机会。 每次需要DisplayObject触发rend...

[cookbook笔记三] colorReduce函数运行效率测试方法

一个很有用的测试图像处理运行耗时的方法为double duration; duration = static_cast(cv::getTickCount()); colorReduce(image);...

09读书笔记之提升ListView的运行效率

提升运行效率

Java基础学习总结(72)——提升 java 代码的运行效率

前言 代码 优化 ,一个很重要的课题。可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?...

python学习五:执行linux命令的两种方法、提高运行效率、进制转换、切片详解、ip和mac获取

1. 执行linux命令 (1)import os      os.system('ls -l')  (2) import subprocess      subprocess.call(...

mysql 学习记录(二十一)--调整linux I/O以提高mysql运行效率

一、概念: 1.使用磁盘阵列 RAID译成中文为“廉价磁盘冗余阵列”。简称“磁盘阵列” 2.常见raid级别: a.raid 0:条带化,将数据依次分布 b.raid 1:磁盘镜像,两个磁盘一组,写入...
  • bwshqh
  • bwshqh
  • 2015年11月03日 23:16
  • 1647

运行效率分析系统

  • 2016年02月17日 15:17
  • 2.3MB
  • 下载

Java8学习笔记(3) -- InvokeDynamic指令在Groovy里的使用

上一篇文章以Java8的Lambda表达式为切入点,讨论了
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Groovy 学习笔记3 运行效率
举报原因:
原因补充:

(最多只允许输入30个字)