The generic method of accessing the data is slowest (about 4 times). You can speed things up by adding a simple switch statement to typecast the generic object to the correct type object. Having seperate loops for each type will speed this even more up. Fastest is to do a getData() typecast the result to the correct type and access the array directly. However this is also the most code and most errorprone, while generic methods is the least code and less errorprone. Best is to use the generics while developping code, and switch to specifics when optimizing the code.
loop size is | 7500000 | |
---|---|---|
Testing direct | 151.6ms | 100% |
Testing function | 181.2ms | 120% |
Testing image type | 204.7ms | 135% |
Testing image check | 225.0ms | 148% |
Testing image generic | 435.9ms | 288% |
As you can see doing a simple check inside the loop, what imagetype it is and typecasting the ImageObject to this this type will speed things up. The reason for the slowdown, is the fact that the abstract class will need to do a runtime check to see what class it really is and call the right function.
So instead of using:ImageObject imageobject; for(i = 0; i < size; i++) { imageobject.set(i, 0); }use:
ImageObject imageobject; for(i = 0; i < size; i++) { switch (imageobject.getType()) { case ImageObject.TYPE_BYTE: ((ImageObjectByte)imageobject).set(i, 0); break; case ImageObject.TYPE_SHORT: ((ImageObjectShort)imageobject).set(i, 0); break; case ImageObject.TYPE_INT: ((ImageObjectInt)imageobject).set(i, 0); break; case ImageObject.TYPE_LONG: ((ImageObjectLong)imageobject).set(i, 0); break; case ImageObject.TYPE_FLOAT: ((ImageObjectFloat)imageobject).set(i, 0); break; case ImageObject.TYPE_DOUBLE: ((ImageObjectDouble)imageobject).set(i, 0); break; } }of course better is:
switch (imageobject.getType()) { case ImageObject.TYPE_BYTE: ImageObjectByte imgbyte = (ImageObjectByte)imageobject; for(i = 0; i < size; i++) { imgbyte.set(i, 0); } break; .... case ImageObject.TYPE_DOUBLE: ImageObjectDouble imgdouble = (ImageObjectDouble)imageobject; for(i = 0; i < size; i++) { imgdouble.set(i, 0); } break; }finally nothing beats:
switch (imageobject.getType()) { case ImageObject.TYPE_BYTE: java.util.Arrays.fill((byte[])(imageobject.getData()), (byte)0); break; .... case ImageObject.TYPE_DOUBLE: java.util.Arrays.fill((double[])(imageobject.getData()), (double)0); break; }Basicly what I am trying to say is, code smart and the speed will follow. If possible use built-in java code like System.arraycopy (which is a single assembly instruction on a x86).