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 阅读(5509) 评论(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.blogjava.net/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.blogjava.net/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,
性能会好一些  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: