Problem details. I need to create a framework to perform various checks, like:
– is Date A between dates B and C?
– is Integer A greater than Integer B and smaller than Integer C?
etc.
So far, i am thinking of two possible implementations, detailed bellow.
Impl1 – using a single class to perform the checks, based on the check type.
import java.sql.Time;
import java.util.Date;
public class SearchManager {
public final static int SEARCH_TYPE_DATE = 0;
public final static int SEARCH_TYPE_INT = 1;
public final static int SEARCH_TYPE_STRING = 2;
public final static int SEARCH_TYPE_TIME = 3;
private final int searchType;
public SearchManager(int searchType) {
this.searchType = searchType;
}
public final boolean doCompare(Object minValue, Object maxValue, Object toBeCompared) {
switch (this.searchType) {
case SEARCH_TYPE_DATE: {
return compareDates((Date) minValue, (Date) maxValue, (Date) toBeCompared);
}
case SEARCH_TYPE_INT: {
return compareIntegers((Integer) minValue, (Integer) maxValue, (Integer) toBeCompared);
}
case SEARCH_TYPE_STRING: {
return compareStrings(String.valueOf(minValue), String.valueOf(maxValue), String.valueOf(toBeCompared));
}
case SEARCH_TYPE_TIME: {
return compareTimes((Time) minValue, (Time) maxValue, (Time) toBeCompared);
}
default:
return false;
}
}
private boolean compareDates(Date min, Date max, Date toBeCompared) {
boolean result = false;
// actual comparison
return result;
}
private boolean compareIntegers(Integer min, Integer max, Integer toBeCompared) {
boolean result = false;
// actual comparison
return result;
}
private boolean compareStrings(String min, String max, String toBeCompared) {
boolean result = false;
// actual comparison
return result;
}
private boolean compareTimes(Time min, Time max, Time toBeComparedDate) {
boolean result = false;
// actual comparison
return result;
}
}
Impl2 – Using an abstract class or interface, and having an implementation of the comparison method for each search type.
public abstract class AbstractSearch {
public final static int SEARCH_TYPE_DATE = 0;
public final static int SEARCH_TYPE_INT = 1;
public final static int SEARCH_TYPE_STRING = 2;
public final static int SEARCH_TYPE_TIME = 3;
public AbstractSearch() {
super(); //just for fun
}
protected abstract boolean doCompare(Object minValue, Object maxValue, Object toBeComparedValue);
}
Now, in this example, for X different search types, as you can imagine, X implementations of the AbstractSearch will be created.
Just imagine yourself that the class AbstractSearch from the 2nd implementation will need to perform additional tasks, other than the method doCompare(..) and that is why an interface is not my 1st candidate for this solution, and to write something like
public abstract class AbstractSearch implements Searcheable
would not help me a lot, since AbstractSearch or SearchManager will handle ALL the comparisons, and, if a new comparison type should be needed, an additional type/subclass implementation will be declared for corresponding super classes from Impl1 or Impl2.
My question is about which implementation is faster? And this is very important, since the comparison process will be called in loops containing thousands of elements.
Thank you for reading/answering my question.
EDIT1: Also, please have in mind the fact that minValue and maxValue will be extracted from the classes that extends the AbstractSearch, for the second example, or classes extending SearchManager, as for the 1st example. These implementation will actually be graphical components allowing the user to enter a minimum and a maximum value, and then, these value will be compared in a loop with some bean property, of objects displayed in a table.
EDIT2: I am doing some benchmarks, with dummy implementations (i just want to compare the method call time vs switch execution time). The results are..surprising:
- Using AbstractSearch (500k loops): -0.047 seconds
- Using SearchManager (500k loops): -0.422 seconds
Having these results, it is safe to assume that using inheritance is much faster than using a switch (or even worse an if-else test) ?
If you want to make this code as fast as possible, also try using overloaded methods like this:
At compile time, the compiler will generate a direct call to the appropriate method, based on the types which you pass. (If you are passing Object references which might point to an instance of any of the 4 types, this won’t work.)
If the values which you are comparing are
ints, passing them to a method which takesObjectarguments will require boxing and unboxing, which adds overhead.If performance is really important, I recommend you use
staticmethods, since they are a bit faster in many Java implementations.Also, rather than using
compareTo, you can probably squeeze out a bit more performance by using your own inline code for the comparisons.EDIT: You said in the edited question that
minandmaxwill actually be passed in by a subclass ofSearchManager. In that case I would makeSearchManagerabstract, and put different implementations ofdoComparein each subclass ofSearchManager. What I said aboutstaticmethods won’t work in this case.