[EMAIL PROTECTED] wrote ([EMAIL PROTECTED])
Well, first of all: sorry I forgot to include the code.. (it's here now).
> I thought the same way as you, until at length I came to the
> conclusion that the classpath people were correct.
>
> Your benchmark just shows that repeatedly checking for a condition
> using an explicit test is faster than using a try/catch block. This
> is true, and noone is arguing against that.
But in the mail I saw on the list they did the oposite. To quote:
"1)Using exceptions versus explicit checks.
I think that for methods that if used normally do not throw exceptions,
checks should be done by exception if possible. For example in
ArrayEnumeration, possibility that nextElement() overflows is very small
(every sane person use hasNextElement() first). So, code could look like
this:
try {
return elements[index++];
} catch ( ArrayOutOfBoundsException e ) {
throw new NoSuchElementException();
}
instead of
if ( index >= elements.length ) throw ...
return elements[index++];
"
Well this got me started and as you can see in the benchmark I rarely have
an exception (1 out of a 100 cases is an exception). Indeed when there
never are exception try/catch is faster. So ok. in this case the optimisation
seems right as there normally should be no exceptions. But when there is
a chance for an excption say 1 out of 1000 calls an explicit check seems
cheaper...
> The reasoning that the classpath people are using is that the
> exceptional condition happens much less frequently than the normal
> condition -- so, by having an explicit test you slow down *everything*
> by the same amount, instead of having the possibility of having most
> things running faster with an occasional slowdown in an exceptional
> case.
Yeah, I wis mis-thinking when I wrote that the try/catch makes it slow, while
it is the throw that really bogs it down.
While I'm on track for performance enhancements, another (although simple)
optimalisation is to optimise for() loops by making sure the breaking
condition-check is cheap. This means that instead of writing:
for(int i=0; i<constant; i++) write:
for(int i=constant-1; i>=0; i--)
A piece of code has been added to the benchmark as well (just noticed
this in some of the code I saw in the Hashtable.java implementation..)
Marcel Ammerlaan
import java.util.*;
public class Benchmark extends Object
{
public static void main(String args[]) {
int i,j;
int runs = 10000;
int arraysize = 100;
int[] a = new int[arraysize+1];
long start;
start = System.currentTimeMillis();
for(i=0; i<runs; i++) {
for(j=0; j<=arraysize; j++) {
try {
if(a[j]!=i)
a[j]=i;
}
catch(Exception e) {
;
}
}
}
System.out.println("Time= " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for(i=0; i<runs; i++) {
try {
for(j=0; j<=arraysize; j++) {
if(a[j]!=i)
a[j]=i;
}
}
catch(Exception e) {
;
}
}
System.out.println("Time= " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for(i=0; i<runs; i++) {
for(j=0; j<=arraysize; j++) {
if(j<a.length)
if(a[j]!=i)
a[j]=i;
}
}
System.out.println("Time= " + (System.currentTimeMillis() - start));
// benchmark 2
start = System.currentTimeMillis();
for(i=0; i<runs; i++) {
for(j=0; j<=arraysize; j++) {
try {
method1(j, a);
}
catch(NoSuchElementException nsee) {
;
}
}
}
System.out.println("Time= " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for(i=0; i<runs; i++) {
for(j=0; j<=arraysize; j++) {
try {
method2(j, a);
}
catch(NoSuchElementException nsee) {
;
}
}
}
System.out.println("Time= " + (System.currentTimeMillis() - start));
// benchmark 3
start = System.currentTimeMillis();
for(i=0; i<(runs*100); i++) {
for(j=0; j<=arraysize; j++) {
;
}
}
System.out.println("Time= " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for(i=0; i<(runs*100); i++) {
for(j=arraysize; j>=0; j--) {
;
}
}
System.out.println("Time= " + (System.currentTimeMillis() - start));
}
public static int method1(int j, int[] a) throws NoSuchElementException {
try {
return a[j++];
}
catch(ArrayIndexOutOfBoundsException aoobe) {
throw new NoSuchElementException();
}
}
public static int method2(int j, int[] a) throws NoSuchElementException {
if(j >= a.length)
throw new NoSuchElementException();
else
return a[j++];
}
}