emu in blogjava

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            171 隨筆 :: 103 文章 :: 1052 評論 :: 2 Trackbacks

           

          第一篇筆記里面,我說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組件。看來對消除性能瓶頸的幫助不大。

          posted on 2005-05-18 18:19 emu 閱讀(6223) 評論(13)  編輯  收藏 所屬分類: Groovy 學習筆記

          評論

          # re: Groovy 學習筆記3 運行效率 2005-06-28 20:38 water
          在Java的世界里, 性能不是最主要的, 開發效率反而更重要些  回復  更多評論
            

          # re: Groovy 學習筆記3 運行效率 2005-06-30 09:57 emu
          不錯,性能不是最主要的,但是并不意味著性能問題不需要考慮。groovy并不只是用來開發原型的。

          我們不做這個考察,在開發的時候怎么會知道什么東西應該用什么方式解決比較好呢。  回復  更多評論
            

          # re: Groovy 學習筆記3 運行效率 2005-09-29 16:17 abcd
          你可以試試看jython  回復  更多評論
            

          # re: Groovy 學習筆記3 運行效率 2005-10-01 00:45 陳朋奕
          jython不成熟……
          其實Java開發并非開發效率最主要,倒是要看什么項目了。而且如果Groovy二次編譯后的Java代碼變成這樣的話,那么可以推測它跟C++的效率之比會有10萬倍以上了。這樣的速度真的難以讓人接受,每個原生類型都Object一下,然后實例化對象就invokeMethod……  回復  更多評論
            

          # re: Groovy 學習筆記3 運行效率 2005-10-03 17:04 順路走過
          腳本是膠水,而不是用來做計算密集型的東西。  回復  更多評論
            

          # re: Groovy 學習筆記3 運行效率 2005-10-04 14:58 emu
          不但腳本不是用來“做計算密集型的東西”的,java也不是c#也不是。正兒八經說,高級語言都不是,匯編語言也只是勉強算是。不是用來“做計算密集型的東西”并非就可以把運行效率完全丟開一邊了。我們犧牲一些運算效率來換開發效率是可以接受的,但是犧牲的太多了就不得不要斟酌一下了。

          秋水無恨解 http://www.aygfsteel.com/emu/category/2769.html 也是用的腳本呢。  回復  更多評論
            

          # re: Groovy 學習筆記3 運行效率 2005-10-26 17:37 cap的技術blog
          測試一下吧,我覺得這個是groovy+jvm自己的問題, 看看python和ruby, 效率比groovy高不少啊, 不算現在的成熟版, 人家最初的那幾個版本一樣也是很快的,同樣是動態語言, 為什么groovy玩得就這么慢呢?

            回復  更多評論
            

          # re: Groovy 學習筆記3 運行效率 2006-06-22 09:49 哈哈的日子
          @emu

          非常支持下面這些話!

          //////////////////////////////////

          不但腳本不是用來“做計算密集型的東西”的,java也不是c#也不是。正兒八經說,高級語言都不是,匯編語言也只是勉強算是。不是用來“做計算密集型的東西”并非就可以把運行效率完全丟開一邊了。我們犧牲一些運算效率來換開發效率是可以接受的,但是犧牲的太多了就不得不要斟酌一下了。

          秋水無恨解 http://www.aygfsteel.com/emu/category/2769.html 也是用的腳本呢。 回復
            回復  更多評論
            

          # re: Groovy 學習筆記3 運行效率 2006-07-11 17:24 甘先生
          支持 emu  回復  更多評論
            

          # re: Groovy 學習筆記3 運行效率 2007-04-21 10:40 zysuper
          雖然我已經看透了groovy的小伎倆,但還是很希望他可以成長起來,現在的groovy實在是太嫩了  回復  更多評論
            

          # re: Groovy 學習筆記3 運行效率 2007-11-13 12:45 順路走過
          @emu
          兄弟,難道根本就不明白什么叫做計算密集型?
          求解np問題從來就沒納入到計算密集型當中。用的最多的都是微分方程方面的求解問題,如氣象,核爆模擬等等。
          這類問題的解決思路都不是深度挖掘單節點的計算能力,而是集群計算的效能和帶寬。
            回復  更多評論
            

          # re: Groovy 學習筆記3 運行效率 2007-11-13 16:07 emu
          呵呵樓上這位兄弟是專業的  回復  更多評論
            

          # re: Groovy 學習筆記3 運行效率 2016-01-20 10:35 良好市民
          使用@CompileStatic,
          性能會好一些  回復  更多評論
            

          主站蜘蛛池模板: 嵩明县| 巩义市| 白沙| 承德市| 闻喜县| 县级市| 南部县| 合川市| 渭源县| 同心县| 雅安市| 平和县| 财经| 崇州市| 龙岩市| 广安市| 勃利县| 乌拉特后旗| 浦江县| 屏东市| 罗山县| 宝鸡市| 酉阳| 平和县| 兴文县| 乌苏市| 五大连池市| 吉木萨尔县| 遂平县| 富源县| 平利县| 拉孜县| 清涧县| 循化| 涟水县| 江陵县| 监利县| 客服| 弋阳县| 商城县| 策勒县|