我试图弄清楚我在代码中创建对象数组的方式是否有问题,或者在 Java 中处理对象数组是否比我最初认为的更昂贵。
我有一个名为 的简单枚举类ElementaryTransitionTerm
,它只包含两个原始成员变量。另一个类中的方法创建一个由该 Enum 的常量组合组成的数组(数组的可能长度永远不会超过 3)。
问题在于,程序在所述方法中总共花费(平均)13ms,尽管它只被调用了 8 次。我不知道为什么。
运行时间通过两种方式计算:
通过 System.nanoTime() 调用围绕对方法的调用。
通过 System.nanoTime() 调用围绕方法内的每个数组创建语句并将它们总结起来
这是ElementaryTransitionTerm枚举类:
public enum ElementaryTransitionTerm
{
MATCH(1, 0), INSERTION(0, 1), SUBSTITUTION(1, 1), DELETION(0, 0), FAILURE(0, 0);
private final int I_OFFSET;
private final int E_OFFSET;
private ElementaryTransitionTerm(int iOffset, int eOffset)
{
I_OFFSET = iOffset;
E_OFFSET = eOffset;
}
}
这是有问题的方法createTransitionTerms(以及用作参数的枚举类型的声明):
//'E' and 'I' are both private int fields in the parent class.
private enum RelevantSubwordHitIndexType { FIRST_INDEX, TRAILING_INDEX, NO_INDEX };
/**
* Creates an array of ElementaryTransitionTerm constants.
* @param hitIndexType a RelevantSubwordHitIndexType enum constant
*/
private ElementaryTransitionTerm[] createTransitionTerms(RelevantSubwordHitIndexType hitIndexType)
{
//Simple getter method chained in to String.length() call
int onePastFinalBoundary = parentAutomaton.getAutomatonString().length();
if(E < parentAutomaton.getMaxEditDistance()) //Simple getter method retrieving an int
{
if(I < onePastFinalBoundary - 1)
{
switch(hitIndexType)
{
case FIRST_INDEX: return new ElementaryTransitionTerm[] {ElementaryTransitionTerm.MATCH};
case TRAILING_INDEX: return new ElementaryTransitionTerm[] {ElementaryTransitionTerm.INSERTION, ElementaryTransitionTerm.SUBSTITUTION, ElementaryTransitionTerm.DELETION};
default: return new ElementaryTransitionTerm[] {ElementaryTransitionTerm.INSERTION, ElementaryTransitionTerm.SUBSTITUTION};
}
}
else if(I == onePastFinalBoundary - 1)
{
switch(hitIndexType)
{
case FIRST_INDEX: return new ElementaryTransitionTerm[] {ElementaryTransitionTerm.MATCH};
default: return new ElementaryTransitionTerm[] {ElementaryTransitionTerm.INSERTION, ElementaryTransitionTerm.SUBSTITUTION};
}
}
else return new ElementaryTransitionTerm[] {ElementaryTransitionTerm.INSERTION};
else
{
if(I < onePastFinalBoundary)
{
switch(hitIndexType)
{
case FIRST_INDEX: return new ElementaryTransitionTerm[] {ElementaryTransitionTerm.MATCH};
default: return new ElementaryTransitionTerm[] {ElementaryTransitionTerm.FAILURE};
}
}
else return new ElementaryTransitionTerm[] {ElementaryTransitionTerm.FAILURE};
}
}
该方法本质上评估一小组条件以创建一个小数组。但是,此方法运行 8 次的总执行时间并不能反映这一点。
我什至public final
在 ElementaryTransitionTerm 中将要返回的数组声明为数组,并将上述方法中的创建语句替换为对这些数组的引用,但这对代码的运行时间完全没有影响。
我编写的代码可以在更短的时间内完成更多工作。所以我很好奇为什么这种方法会这样。有没有人有任何想法?
编辑:
经过进一步测试,我发现了两件事:
- 单独测试该方法会产生预期的(即亚毫秒)结果。
- 在程序中测试该方法,似乎在第一次调用该函数时执行的数组创建语句基本上对我所看到的时间负责。所有后续调用都在亚毫秒时间内完成。
关于#2:这是什么原因,我该如何纠正它?