emu in blogjava

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  171 随笔 :: 103 文章 :: 1052 评论 :: 2 Trackbacks

 author:emu(黄希彤)Groovy 学习笔记3 运行效率 初识Rhino 中都用8皇后问题来比较java,javascript,groovy和Rhino 的运行效率。一开始考虑到8皇后只有92组解,输出占用的时间应该很少,为了好看就把全部结果打印出来了。

后来因为程序运行的太快,又增加了皇后的数目,用9皇后来测试,这样需要输出352个解了,我仍然没有意识到输出对运行时间的影响。直到今天中午多放了一个皇后的时候,才意识到问题的严重性:java版运行10皇后如果不输出结果只需要30~40毫秒,而输出结果的情况下需要500毫秒左右,输出成了速度瓶颈。吧前面的测试全部去掉结果输出部分重新测一遍吧:


java版:

public class queens {
    
static int q=10;
    
static int[] i=new int[q];
    
static int count=0;
    
public static void main(String[] args){
        
long t = System.currentTimeMillis();
        scan(
0);
        System.
out.println("totle results:"+count);
        System.
out.println("totle time:"+(System.currentTimeMillis()-t));
    }

    
private static void scan(int n){
        
if (n==q){
//            for (int k=0;k<q;k++) System.out.print(i[k]+(k==q-1?"\n":","));
            count++;
            
return;
        }

        i[n]
=0;
        
while(i[n]<q){
            i[n] 
= i[n]+1;
            
if (check(n)){
                scan(n
+1);
            }

        }

    }

    
private static boolean check(int n){
        
for(int j=0;j<n;j++){
            
if (i[j]==i[n] || i[j]-i[n]==j-|| i[j]-i[n]==n-j ){
                
return false;
            }

        }

        
return true;
    }

}



javascript(DHTML)版

<SCRIPT LANGUAGE="JavaScript">
<!-- 
var q=10 
var i=[] 
var count=0 
var d = new Date(); 
scan(
0
document.write(
"totle results:"+count+"<br>"
document.write(
"time used:"+(new Date()-d)+"<br>"

function scan(n)
    
if (n==q)
//        document.write(i+"<br>") 
        count++ 
        
return 
    }
 
    i[n]
=0 
    
while(i[n]<q){
        i[n] 
= i[n]+1 
        
if (check(n)){
            scan(n
+1
        }
 
    }
 
}
 

function check(n)
    
for (var j=0; j<n;j++)
        
if (i[j]==i[n] || i[j]-i[n]==j-|| i[j]-i[n]==n-j )
            
return false  
    
return true 
}
 
//--> 
</SCRIPT> 


groovy版

int q=10
int[] i=new int[q]
int count=0
long t = System.currentTimeMillis();
scan(
0)
println(
"totle results:"+count)
println(
"totle time:"+(System.currentTimeMillis()-t));
def scan(n)
{
    
if (n==q){
//        println(i.toList())
        count++
        
return
    }

    i[n]
=0
    
while(i[n]<q){
        i[n] 
= i[n]+1
        
if (check(n))
            scan(n
+1)
    }

}

def check(n)
{
    
if (n>0)
        
for (j in 0..<n) 
            
if (i[j]==i[n] || i[j]-i[n]==j-|| i[j]-i[n]==n-j )
                
return false
    
return true
}


javascript(Rhino)版

var q=10
var i
=[] 
var count
=0 
var d 
= new Date(); 
scan(
0
print(
"totle results:"+count) 
print(
"time used:"+(new Date()-d)) 

function scan(n)

    
if (n==q)
//        print(i) 
        count++ 
        
return 
    }
 
    i[n]
=0 
    
while(i[n]<q){
        i[n] 
= i[n]+1 
        
if (check(n)){
            scan(n
+1
        }
 
    }
 
}
 

function check(n)

    
for (var j=0; j<n;j++)
        
if (i[j]==i[n] || i[j]-i[n]==j-|| i[j]-i[n]==n-j )
            
return false  
    
return true 
}
 


其中javascript版由于在IE上运行的时间刚好超过5秒,会收到一个警告,所以是在firefox上测的。


在我的笔记本上测试结果是:
java 版:
---------- run ----------
totle results:724
totle time:40
Normal Termination
输出完成(耗时 0 秒)。


javascript(DHTML)版
 totle results:724
time used:4977

groovy版

用groovy命令运行:
---------- run ----------
totle results:724
totle time:31095
Normal Termination
输出完成(耗时 32 秒)。

用groovyconsole运行或者编译成java class后用java命令运行的结果也差不多,都在30~36秒之间。


javascript(Rhino)版
---------- run ----------
totle results:724
time used:3685
Normal Termination
输出完成(耗时 4 秒)。

结果是:Rhino运行javascript脚本比firefox快一点(而firefox似乎又比IE快一点),总的来说,在这个测试上javascript比java慢一个数量级,而groovy则比javascript慢一个数量级author:emu(黄希彤)

posted on 2005-06-22 14:30 emu 阅读(2732) 评论(7)  编辑  收藏

评论

# re: java,javascript,groovy和Rhino 的运行效率到底相差的有多远? 2005-06-30 15:21 emu
昨天自己做了一点点优化:
function check(n){
for (var j=0; j<n;j++)
if (i[j]==i[n] || i[j]-i[n]==j-n || i[j]-i[n]==n-j )
return false
return true
}

改为

function check(n){
for (var j=0,c=i[n],b=n; j<n;j++,b--){
var d = i[j];
if (d==c) return false
var a = d-c
if (a==b||a==-b) return false
}
return true
}

只是少访问几次数组,少做几次减法运算,好像差别不大。但是由于check函数处在循环的最里层,优化的结果是在Rhino下面算11皇后的时候快了一倍左右,在cscript下面没有那么突出,但也明显也快了不少。  回复  更多评论
  

# re: java,javascript,groovy和Rhino 的运行效率到底相差的有多远? 2005-11-24 17:23 yorry
请问如何在rhino中使用浏览器对象?谢谢。  回复  更多评论
  

# re: java,javascript,groovy和Rhino 的运行效率到底相差的有多远? 2005-11-25 18:08 emu
只有在浏览器中运行脚本的时候才能访问浏览器对象。
有的时候我们想在非浏览器的上下文中测试一个函数的功能,可以用脚本模拟一个navigator、window或者document对象并赋相应的属性和模拟的方法进去。  回复  更多评论
  

# re: java,javascript,groovy和Rhino 的运行效率到底相差的有多远? 2005-11-28 11:15 yorry
也就是rhino本身并没有提供模拟出浏览器上下文这样的功能?看来rhino果然和浏览器不直接发生交互。  回复  更多评论
  

# re: java,javascript,groovy和Rhino 的运行效率到底相差的有多远? 2005-11-28 22:20 emu
很多人都把DHTML当成是JAVASCRIPT,把window、document、body当成javascript语言提供的内嵌对象。其实不但rhino,其他javascript引擎本身也都不支持浏览器对象的。玩过cscript/wscript吗?
  回复  更多评论
  

# re: java,javascript,groovy和Rhino 的运行效率到底相差的有多远? 2005-12-02 14:35 sheerfreedom
emu 浏览器对象到底怎么模拟呢 ?

比如说document对象

能给个例子看看吗 ?  回复  更多评论
  

# re: java,javascript,groovy和Rhino 的运行效率到底相差的有多远? 2005-12-02 14:56 emu
这要看测试范围了,单一个document每什么好测的,要模拟的话 var document=new Object(); 就可以了。要测试它的相关属性和方法就要用脚本构造出来。比如我们有一个函数要修改document的title属性:

function changeTitle(){
// 这是被测试的函数,其中使用了document对象的title属性
document.title += " -- emu";
}

我们可以这样测试它:

var document=new Object();//模拟document对象
document.title = "试一试";//模拟title属性
changeTitle();
if(document.title=="试一试 -- emu")
WScript.Echo("函数changeTitle测试通过") ;
else
WScript.Echo("函数changeTitle测试失败") ;

注意到这里用了WScript.Echo输出,直接在cscript或者wscript脚本宿主中运行就可以了。如果用rhino的话就print。  回复  更多评论
  


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


网站导航: