まず、これまでに示したメソッドの複雑さを見てみましょう。
- はk 個のチェック
ifForMethod
を実行し、そのうちm個は true を返します。これらのmごとに、 n 個のオブジェクトに対する反復があります。したがって、複雑さはk+nmです。
- はn 個のオブジェクトを
forIfMethod
反復し、反復ごとにk回の比較を実行します。したがって、複雑さはk+n(k-1)=nkです。
どちらの場合も、すべてのk条件を少なくとも 1 回評価する必要があるため、ここでの違いは実際にはnmとn(k-1) の加数にあります。漸近的に、mはkのほんの一部です( mは約.75kであると言った)、これらは両方とも O( nk ) ですが、k+nm < k+n(k-1)であるため、ifForMethod
よりも高速である可能性があります。forIfMethod
. 実際の実行時間の違いは、配列の反復処理に実際にかかる時間やkの大きさなどの要因によって異なります。. メモリの局所性 (オブジェクトとコードの両方) などの問題が発生し始めます。
ただし、興味深いと思われるアプローチを次に示します。理想的には、オブジェクトのリストを 1 回だけ反復処理し、ブール条件を複数回チェックする必要はありません。実行中のアクションを抽象化して、それらを単一のアクションに結合できるようにし (真の条件に対応するアクションのみを組み込むことができます)、次にその複合アクションを実行できます。リスト内の各要素。これを行うコードを次に示します。
doA
アイデアは、アクションがあり、実行するアクションと実行するアクションを構築できるということですdoB
。条件に基づいて、条件が true の場合のアクションと条件が true のdoA
場合のアクションを含む複合アクションを作成できます。次に、オブジェクトを繰り返し処理し、各オブジェクトに対して複合アクションを呼び出します。漸近的には、これはk+nmメソッドであるため、理論的にはうまく機能しますが、ここでも、実際のパフォーマンスは、いくつかのトリッキーな定数とメモリの局所性の問題に依存します。doA
doB
doB
import java.util.ArrayList;
import java.util.List;
public class CompoundActionExample {
/**
* An action is used to do something to an argument.
*/
interface Action {
void act( Object argument );
}
/**
* A compound action is an action that acts on an argument
* by passing the argument to some other actions.
*/
static class CompoundAction implements Action {
/**
* The list of actions that the compound action will perform. Additional
* actions can be added using {@link #add(Action)}, and this list is only
* accessed through the {@link #act(Object)} method.
*/
private final List<CompoundActionExample.Action> actions;
/**
* Create a compound action with the specified list of actions.
*/
CompoundAction( final List<CompoundActionExample.Action> actions ) {
this.actions = actions;
}
/**
* Create a compound action with a fresh list of actions.
*/
CompoundAction() {
this( new ArrayList<CompoundActionExample.Action>() );
}
/**
* Add an action to the compound action.
*/
public void add( CompoundActionExample.Action action ) {
actions.add( action );
}
/**
* Act on an argument by passing the argument to each of the
* compound action's actions.
*/
public void act( final Object argument) {
for ( CompoundActionExample.Action action : actions ) {
action.act( argument );
}
}
}
public static void main(String[] args) {
// Some conditions and a list of objects
final boolean conditionA = true;
final boolean conditionB = false;
final Object[] listOfObjects = { "object1", "object2", "object3" };
// A compound action that encapsulates all the things you want to do
final CompoundAction compoundAction = new CompoundAction();
// If conditionA is true, add an action to the compound action that
// will perform doA. conditionA is evaluated exactly once.
if ( conditionA ) {
compoundAction.add( new Action() {
public void act( final Object argument) {
System.out.println( "doA("+argument+")" ); // doA( argument );
}
});
}
// If conditionB is true, add an action to the compound action that
// will perform doB. conditionB is evaluted exactly once.
if ( conditionB ) {
compoundAction.add( new Action() {
public void act(Object argument) {
System.out.println( "doB("+argument+")" ); // doB( argument );
}
});
}
// For each object, apply the compound action
for ( final Object o : listOfObjects ) {
compoundAction.act( o );
}
}
}