3

私は iPhone に Cocos2d を使用していますが、この方法を使用して敵をスポーンするコードのロジックを構築する方が効率的かどうか疑問に思っています。

-(無効) スケジュール:(SEL)セレクタ間隔:(ccTime)間隔

または EnemyCache クラスで更新を使用して、時間間隔が満たされているかどうかを毎回確認します。EnemyCache クラスの update メソッドで呼び出されるコード スニペットを次に示します (相対時間は、GameScene クラスの更新ごとに GameScene によって更新される整数値です。GameScene 更新メソッドの呼び出しは、1 の間隔でスケジュールされます。 2番目):

-(void) checkForPlayerCollisionsAndSpwanTime
{


    int count = [elements count];
    //CCLOG(@"count %i", count);
    Element* element;
    for(int i=0; i<count;i++){

        element = [elements objectAtIndex:i];
        NSAssert(element!=nil, @"Nil enemy");

        if (element.visible)
        {
            [element justComeDown];
            ShipEntity * ship = [[GameScene sharedGameScene]defaultShip];
            CGRect rect = [ship boundingBox];

            if (CGRectIntersectsRect([element boundingBox], rect)){
                [element doWhatever]; 
                element.visible=FALSE;
                [element stopAllActions];
            }       
        }
        else{
            if(element.spawnTime == relativeTime) {
                [self addChild:element]; 
                element.visible=TRUE;
            }
        }
    }
}

違いは、このように更新のたびにcheckForPlayerCollisionsAndSpwanTimeメソッドが敵の配列を通過することです。最初の方法では、同様のメソッドを呼び出すようにセレクターをスケジュールすることで、配列と条件を調べるために CPU が費やす時間を削減できました。

この呼び出しがどれほどコストがかかるかはわかりません。

[self schedule:selector interval:interval repeat:kCCRepeatForever delay:0];

よく見ると、このメソッドが呼び出されていることがわかります (以下を参照) が、一般的に、この問題に対するあなたのアプローチと、EnemyCache 更新メソッドを使い続けるか、または scheduleSelector メソッドを使用する必要があるかを尋ねたかったのです。

-(void) scheduleSelector:(SEL)selector forTarget:(id)target interval:(ccTime)interval paused:(BOOL)paused repeat:(uint) repeat delay:(ccTime) delay
{
    NSAssert( selector != nil, @"Argument selector must be non-nil");
    NSAssert( target != nil, @"Argument target must be non-nil");

    tHashSelectorEntry *element = NULL;
    HASH_FIND_INT(hashForSelectors, &target, element);

    if( ! element ) {
        element = calloc( sizeof( *element ), 1 );
        element->target = [target retain];
        HASH_ADD_INT( hashForSelectors, target, element );

        // Is this the 1st element ? Then set the pause level to all the selectors of this target
        element->paused = paused;

    } else
        NSAssert( element->paused == paused, @"CCScheduler. Trying to schedule a selector with a pause value different than the target");


    if( element->timers == nil )
        element->timers = ccArrayNew(10);
    else
    {
        for( unsigned int i=0; i< element->timers->num; i++ ) {
            CCTimer *timer = element->timers->arr[i];
            if( selector == timer->selector ) {
                CCLOG(@"CCScheduler#scheduleSelector. Selector already scheduled. Updating interval from: %.4f to %.4f", timer->interval, interval);
                timer->interval = interval;
                return;
            }
        }
        ccArrayEnsureExtraCapacity(element->timers, 1);
    }

    CCTimer *timer = [[CCTimer alloc] initWithTarget:target selector:selector interval:interval repeat:repeat delay:delay];
    ccArrayAppendObject(element->timers, timer);
    [timer release];
}
4

1 に答える 1

4

アプリのパフォーマンスに問題がありますか? そうでない場合、答えは次のとおりです。もしそうなら、あなたはそれを測定しましたか、そして問題は問題の方法から生じましたか? そうでない場合、答えは次のとおりです。間違った場所を探しています。

つまり、時期尚早の最適化は諸悪の根源です

それでも知りたい場合は、調べる方法が 1 つだけあります。コードの両方のバリアントを測定し、より高速な方を選択します。速度の差が最小限である場合 (そうなると思います)、作業しやすいバージョンを優先してください。考慮すべき別の種類のパフォーマンスがあります。人間として、コードを読み、理解し、変更します。コードの可読性と保守性は、ほとんどすべての状況でパフォーマンスよりもはるかに重要です。

この量のコードを見て、「はい、A は間違いなく約 30 ~ 40% 高速です。A を使用してください」と結論付けることはできません (またはすることはありません)。メソッドの速度が気になる場合は、どちらが速いか誰にも言わせないでください。それを測定します。それがあなたが確信できる唯一の方法です。

その理由は次のとおりです。プログラマーは、コードのパフォーマンスについて仮定を立てることで悪名高いです。彼らが最後に測定したとき、言語やハードウェア、またはトピックの理解が大きく飛躍したため、多くの場合、彼らは間違っています。しかし、彼らが学んだことを覚えている可能性は高いです。なぜなら、彼らはあなたと同じような質問をし、他の誰かが彼らに答えを与え、それ以降は事実として受け入れたからです.

しかし、あなたの特定の例に戻って、それは本当に問題ではありません. いつスポーンするかを決定するコードよりも多くの敵をレンダリングすることにより、パフォーマンスの問題が発生する可能性が非常に高くなります。そして、そのコードがスケジュールされたセレクターで実行されるか、フレームごとにカウンターを増やすスケジュールされた更新メソッドで実行されるかは、本当に、本当に、本当に、本当に、本当に問題ではありません。これは、パフォーマンスに関する決定よりも、主観的なコーディング スタイルの好みの問題に要約されます。

于 2012-07-12T19:41:58.320 に答える