速度分析器 - 基于参数类型的抽象方法或开关

时间:2012-02-24 22:10:20

标签: java performance design-patterns compare abstract

问题详情。我需要创建一个框架来执行各种检查,例如: - 是日期B和C之间的日期A? - 整数A是否大于整数B且小于整数C? 等等 到目前为止,我正在考虑两种可能的实现方式,详见下文。

Impl1 - 使用单个类根据检查类型执行检查。

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 - 使用抽象类或接口,并为每种搜索类型实现比较方法。

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);

}

现在,在此示例中,对于X种不同的搜索类型,您可以想象,将创建AbstractSearch的X实现。

想象一下,第二个实现中的类AbstractSearch将需要执行除doCompare(..)方法之外的其他任务,这就是为什么接口不是我解决此问题的第一个候选者,并且写点像

public abstract class AbstractSearch implements Searcheable

对我没什么帮助,因为AbstractSearchSearchManager将处理所有比较,并且,如果需要新的比较类型,将声明一个额外的类型/子类实现用于相应的来自Impl1或Impl2的超级课程。

我的问题是哪个实施更快?这非常重要,因为比较过程将在包含数千个元素的循环中调用。 感谢您阅读/回答我的问题。

EDIT1 :另外,请记住,minValue和maxValue将从扩展AbstractSearch的类中提取,第二个示例或扩展{{1对于第一个例子。这些实现实际上是允许用户输入最小值和最大值的图形组件,然后,这些值将在循环中与表中显示的对象的某些bean属性进行比较。

EDIT2 :我正在做一些基准测试,使用虚拟实现(我只想比较方法调用时间与交换机执行时间)。结果令人惊讶:

  • 使用AbstractSearch(500k循环): - 0.047秒
  • 使用SearchManager(500k循环): - 0.422秒

有了这些结果,可以安全地假设使用继承比使用交换机快得多(或者更糟糕的是if-else测试)?

4 个答案:

答案 0 :(得分:1)

我认为最好的想法是结合两种想法(并使其更安全)并利用您在示例中提供的所有类型(日期,时间,字符串和整数)这一事实是可比较的

public final <A> boolean doCompare (Comparable<A> min, Comparable<A> max, A target)
{
   return (min.compareTo(target) < 0) && (max.compareTo(target) > 0)
}

这肯定比第一次实现快得多,因为它不需要进行任何类型检查(所有检查都将在编译时完成)并且类型更安全且不慢于第二次(同时对类型也更灵活) )。

答案 1 :(得分:1)

如果您想尽快制作此代码,请尝试使用这样的重载方法:

public final static boolean doCompare(Date min, Date max, Date toCompare) {
  // ...
}
public final static boolean doCompare(int min, int max, int toCompare) {
  // ...
}
// ...and so on

在编译时,编译器将根据您传递的类型生成对相应方法的直接调用。 (如果您传递的Object引用可能指向4种类型中的任何一种的实例,则不起作用。)

如果您要比较的值是int s,将它们传递给带有Object参数的方法将需要装箱和拆箱,这会增加开销。

如果性能非常重要,我建议您使用static方法,因为它们在许多Java实现中速度要快一些。

此外,您可以使用自己的内联代码进行比较,而不是使用compareTo,而不是通过使用内联代码来提高性能。

编辑:您在编辑过的问题中说minmax实际上将由SearchManager子类传入。在这种情况下,我会SearchManager abstract,并在doCompare的每个子类中放置SearchManager的不同实现。我对static方法所说的内容在这种情况下不起作用。

答案 2 :(得分:0)

这只是你可以做比较的事吗? (它看起来像。)这种方法对于所有三种实现都基本相同吗?

如果是这样,请写下

static <T extends Comparable<T>> boolean doCompare(T min, T max, T toCompare) {
  // impl here
}

答案 3 :(得分:0)

有趣的问题!为什么不对两种实现进行基准测试?