我在读“Effective Java”的时候看到这样一段话:The exception-based idiom is far slower than the standard one on virtually all current JVM implementation.  On my machine, the exception-based idiom runs seventy times slower than the standard one when looping from 0 to 99.
我的理解是:在几乎现在所有的java虚拟机的执行过程中,基于异常的语句的执行效率要远远慢于标准语句。他的意思是不是说,如果一个语句被try-catch包裹起来的话,那么它的执行效率就会降低?
于是我想用下面的程序证明这句话:public class TestEfficiency
{ public static void main(String[] args)
{
int i;
int[] a,b;
//int[] a=new int[100];
long StartTime,StopTime;
StartTime=System.currentTimeMillis();
a=new int[100];
        for(i=0;i<100;i++)
        {
a[i]=i; } System.out.println("Start Time:"+StartTime);
for(i=0;i<100;i++)
{
System.out.println("value of array a[]="+a[i]);
}
StopTime=System.currentTimeMillis();
System.out.println("Stop Time:"+StopTime);
System.out.println("Used Time="+(StopTime-StartTime)); StartTime=System.currentTimeMillis();
for(i=0;i<100;i++)
{
try
{
            System.out.println("value of array a[]="+a[i]);
}catch(Exception e)
{
e.printStackTrace();
} }
    StopTime=System.currentTimeMillis();
        System.out.println("Used Time="+(StopTime-StartTime));
}
}但是结果并不对,两个used time的时间相差无几。
我想我可能是理解错了,关键是“exception-based idiom”是什么意思?
请大家指教。谢谢!~!!~

解决方案 »

  1.   

    顶 treeroot(旗鲁特) 下
    说的对是静安寺不是道明寺,是源程序不是言承旭;是在静安寺写源程序,不是在流星花园看F4。
      

  2.   

    但是发生异常的话,程序就终止了,怎么能知道执行时间呢?
    我写了如下的程序,但是也得不到想要得结果。 b数组的运行时间最后并没有打印出来。 只把异常信息打出来了。import java.util.*;public class TestEfficiency
    { public static void main(String[] args)
    {
    int i;
    int[] a,b;
    ArrayList list=new ArrayList();
    //int[] a=new int[100];
    long StartTime,StopTime;
    StartTime=System.currentTimeMillis();
    System.out.println("Start Time:"+StartTime);
    for(i=0;i<100;i++)
    {
    list.add(new Integer(i));
    } a=new int[list.size()];
    for(i=0;i<list.size();i++)
    {
    a[i]=((Integer)list.get(i)).intValue();
    System.out.println("value of array a[]="+a[i]);
    }
    StopTime=System.currentTimeMillis();
    System.out.println("Stop Time:"+StopTime);
    System.out.println("Used Time="+(StopTime-StartTime)); b=new int[list.size()];
    StartTime=System.currentTimeMillis();
    for(i=0;;i++)
    {
    try
    { b[i]=((Integer)list.get(i)).intValue();
            System.out.println("value of array b[]="+b[i]);
    }catch(ArrayIndexOutOfBoundsException e)
    {
                          StopTime=System.currentTimeMillis();
        System.out.println("Used Time="+(StopTime-StartTime));
        e.printStackTrace();
    } }
    }
    }打印结果:
    ... ...
    value of array b[]=98
    value of array b[]=99
    Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 100, Size
    : 100
            at java.util.ArrayList.RangeCheck(Unknown Source)
            at java.util.ArrayList.get(Unknown Source)
            at TestEfficiency.main(TestEfficiency.java:37)
    要怎样才能证明exception-based idiom的效率比standard idiom低呢?请指教!
    谢谢!~!
      

  3.   

    效率应该会降低,try后的语句必须要记录此刻的执行状态,以便发生异常时判断该如何处理,你的试验得出的数值并不一定确切,再说你每次运行的数值也是不同的。
      

  4.   

    代码的执行是一个压栈和出栈的过程,在使用了try catch 时,jvm要记录代码的运行状态:try进栈入口,当错误发生时,从哪里退出
      

  5.   

    现在的机器性能对程序在catch到runtimeException时性能的影响也许不是太大,但如果使用了自定义的Exception,那么就要涉及到楼上look_所说的压栈和出栈问题以及自定义Exception对象的实例化和处理等等,这样一来,效率的影响可想而知.Effective Java前段时间我也看过,的确是本好书,不过有些条目也不是是绝对的,都要看具体的情况而定.
      

  6.   

    谢谢诸位!~!我想应该是机器发展的很快的原因,使得现在异常对效率的影响小多了。另外,又仔细读了一下,我认为"execptional-based"应该是指异常发生的情况,而不仅仅是有try-catch语句就行了。
    还有,0-99太少了, 基本测不出来时间差。下面的程序测试了一下给数组赋值0-100000时,正常情况下和出现异常时的时间,后者大概是前者的20倍左右吧。import java.util.*;public class TestEfficiency
    { public static void main(String[] args)
    {
    int i;
    int[] a,b;
    ArrayList list=new ArrayList();
    //int[] a=new int[100];
    long StartTime,StopTime;
    StartTime=System.currentTimeMillis();
    System.out.println("Start Time:"+StartTime);
    for(i=0;i<100000;i++)
    {
    list.add(new Integer(i));
    } a=new int[list.size()];
    for(i=0;i<list.size();i++)
    {
    a[i]=((Integer)list.get(i)).intValue();
    //System.out.println("value of array a[]="+a[i]);
    }
    StopTime=System.currentTimeMillis();
    System.out.println("Stop Time:"+StopTime);
    System.out.println("Used Time="+(StopTime-StartTime)); b=new int[list.size()];
    StartTime=System.currentTimeMillis();
    try
    { for(i=0;;i++)
    { b[i]=((Integer)list.get(i)).intValue();
            // System.out.println("value of array b[]="+b[i]);} }catch(ArrayIndexOutOfBoundsException e)
    {
    StopTime=System.currentTimeMillis();
        System.out.println("Used Time="+(StopTime-StartTime));
    //e.printStackTrace();
    }finally
    {
                    StopTime=System.currentTimeMillis();
                    System.out.println("Used Time="+(StopTime-StartTime));
    }
    }
    }
    谢谢诸位!~!!              *v*
      

  7.   

    对于那句话的理解,我觉得不是说把一句话包括在try块里和不包在try块里的区别。
    他说的70倍是指 一个程序有多个分支,这些分支通过异常来处理的话,比条件判断语句带来的结果慢70倍。
    比如说,a/b。如果b=0时,返回a。
    可以写成if(b!=0)
    {
      return a/b;
    }
    else 
    {
    return a;
    }
    也可以写成
    try
    {
    return a/b;
    }
    catch(Exception e)
    {
    return a;
    }第二种方法耗费的时间是第一种的70倍。