zoukankan      html  css  js  c++  java
  • Groovy 学习笔记3 运行效率

    第一篇笔记里面,我说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组件。看来对消除性能瓶颈的帮助不大。

  • 相关阅读:
    SSH框架——Sprign声明式事务
    SSH框架的简化
    Spring声明式事务管理
    简化注解shh框架
    ssh 的搭建
    基础篇-spring包的下载
    基础篇-struts2的搭建
    spring声明式事务管理
    shh简化
    shh(struts+spring+Hibernate)的搭建
  • 原文地址:https://www.cnblogs.com/stonehuang/p/6603237.html
Copyright © 2011-2022 走看看