是否可以使用异常来检查数组边界? [英] Is it OK to use exceptions to check for array boundaries?

查看:175
本文介绍了是否可以使用异常来检查数组边界?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想检查给定的坐标是否带有数组。

I want to check whether the given coordinates are withing an array or not.

public boolean checkBounds(int x, int y) {
    try {
        Object val = array[x][y];
        return true;
    } catch (ArrayIndexOutOfBoundsException e) {
        return false;
    }
}

我能这样做吗?它是一种有效的方法吗?

Can I do it like that? Is it an efficient way to do it?

推荐答案

当我们使用异常来执行边界检查时会发生什么?



使用异常处理空检查,边界检查,文件存在检查等操作会在抛出异常时引入大量开销。

What happens when we use exceptions to perform boundary checks?

Using exceptions for handling operations like null checking, bounds checking, file existance checking introduces a lot of overhead whenever the exception is thrown.

如果您只是检查边界,您会做什么:

What you would have done if you simply checked the bounds:


  • 检查数组的大小是否为0而不是

  • 返回结果

使用基于异常的检查时您实际在做什么:

What you actually are doing when using exception-based checking:


  • 检查数组的边界

  • 启动java异常机制(及其所有开销)

  • 创建一个新的异常对象

  • 转储整个堆栈跟踪

  • 用新堆栈数据填充新创建的对象

  • 捕获异常

  • 返回结果

  • check the bounds of the array
  • initiate java exceptions mechanism (with all its overhead)
  • create a new Exception object
  • dump entire stack trace
  • fill the newly created object with all stack data
  • catch the exception
  • return the result

通过这个简单的测试程序,我测量了两种类型的数组边界检查的速度。

With this simple test program, I have measured the speed of both types of array boundary checks.

public class BoundsCheckTest {

    final static int[] array = new int[1];
    final static Random gen = new Random();

    public static void main(String[] args){

        boolean ret = false;
        int tries = 100000000;
        long timestart = System.nanoTime();

        for (int a=0; a< tries; a++) {
            ret = method1();
        }
        long timeend1 = System.nanoTime();
        System.out.println();

        for (int a=0; a< tries; a++) {
            ret = metod2();
        }
        long timeend2 = System.nanoTime();
        System.out.println();


        long t1 = timeend1-timestart;
        long t2 = timeend2-timeend1;
        System.out.println("\ntime 1=["+t1+"]\n     2=["+t2+"]"+
                 "\ndiff=["+Math.abs(t1-t2)+"] percent diff=["+(100d*t2/t1-100)+"]");

    }

    private static boolean metod2() {
        try {
            int val = array[gen.nextInt(2)];
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    private static boolean method1() {
        return array.length < gen.nextInt(2);
    }

}

结果:

JDK 7,eclipse 模式运行:

JDK 7, eclipse Run as mode:

time check=[911620628]
       exc=[1192569638]
diff=[280949010] percent diff=[30.818632375220886]

JDK 7,eclipse 调试模式:

JDK 7, eclipse Debug mode:

time check=[931243924]
       exc=[651480777121]
diff=[650549533197] percent diff=[69858.12378809143]

禁用调试时的速度损失不是很显着,尽管它是可见的:没有例外的代码速度提高了约30%(大约50%的错误回报)。调试模式下的速度损失是惊人的。基于异常的代码比正常的直接数组大小检查运行速度慢约700倍。

The speed loss with debugging disabled is not very significant, though it is visible: code without exceptions is about 30% faster (for roughly 50% of false returns). The speed loss in debug mode is astonishing. The exception-based code runs about 700 times slower than the normal straight-up array size check.

例外背后的一般思想是允许一种处理 exceptiona 条件的方法。在这种情况下,根本没有异常条件 - 范围检查只是代码的正常部分。仅仅因为这个原因,在这种情况下不应该使用例外。

The general idea behind exceptions is to allow a way to handle exceptiona conditions. In this case, there is no exceptional condition at all - the range check is just a normal part of code. For that reason alone the exception should not be used in this situation.

这篇关于是否可以使用异常来检查数组边界?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆