问题
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?
回答1:
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:
- check the size of an array against 0 and against the
- return result
What you actually are doing when using exception-based checking:
- 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
Performance comparison
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);
}
}
The results:
JDK 7, eclipse Run as
mode:
time check=[911620628]
exc=[1192569638]
diff=[280949010] percent diff=[30.818632375220886]
JDK 7, eclipse Debug
mode:
time check=[931243924]
exc=[651480777121]
diff=[650549533197] percent diff=[69858.12378809143]
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.
Philosophy of exceptions
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.
来源:https://stackoverflow.com/questions/18872733/is-it-ok-to-use-exceptions-to-check-for-array-boundaries