0

Objective Cの循環バッファに1秒に何回も複素数の配列を追加します。Objective Cで循環バッファを実装して高性能を実現する方法

現在、別のNSMutableArray(2D配列)内にNSMutableArrayをネストしています。これは正常に動作しますが、私たちのニーズには遅すぎます。

循環バッファに1秒間に何回も追加したいと考えています。これを実行してパフォーマンスを監視すると、removeObjectAtIndex:0の呼び出しがボトルネックになります(n-1オブジェクトまたはO(n-1)シフト)。これは、循環バッファに数千ものエントリがあるためです。

STLとstd :: dequeを使用している可能性があります。また、CHDataStructuresも見てきました。ご存じのように、STLはC++で提供されており、統合することはできますが、Objective Cソリューションほど単純ではありません。 CHDataStructuresは日付が付いていて、ARCに準拠していません。

可能であれば、コードサンプルを使用して高性能を実現する環状バッファ(double型の配列)を実装する方法をお勧めします。

答えて

0

私は通常のNSArrayの使用がメモリ管理上の問題がないので(NSArraysは自然にオブジェクトを保持しているので)、あなたのコメントを読んだことがあります。実行時にメモリを再割り当てする必要がないように、容量を前もって定義してください。 [self resetBuffer]を呼び出すと、すばやくすべてのデータが解放され、再び開始されます。

#define BUFFER_SIZE 1000 

@implementation ViewController { 
    NSMutableArray *circularBuffer; 
    NSUInteger bufferHead; 
} 

- (instancetype)initWithCoder:(NSCoder *)aDecoder { 
    if (self = [super initWithCoder:aDecoder]) { 
     [self resetBuffer]; 
    } 
    return self; 
} 

- (void)addArrayToBuffer:(NSMutableArray *)incoming { 

    if (bufferHead < circularBuffer.count) 
     [circularBuffer replaceObjectAtIndex:bufferHead withObject:incoming]; 
    else 
     [circularBuffer addObject:incoming]; 

    bufferHead = (bufferHead + 1) % BUFFER_SIZE; 
} 

- (NSArray *)bufferContent { 

    if (circularBuffer.count < BUFFER_SIZE) { 
     return circularBuffer; 
    } else { 
     NSArray *arrHead = [circularBuffer objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, bufferHead)]]; 
     NSArray *arrTail = [circularBuffer objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(bufferHead, BUFFER_SIZE-bufferHead)]]; 

     return [arrTail arrayByAddingObjectsFromArray:arrHead]; 
    } 
} 

- (void)resetBuffer { 
    circularBuffer = [NSMutableArray arrayWithCapacity:BUFFER_SIZE]; 
    bufferHead = 0; 
} 
+0

これは興味深いようです。私はあなたのためにいくつか質問があります。 1. circularBuffer NSMutableArrayでCFBridgingReleaseとCFBridgingRetainを使用しているのはなぜですか? circularBufferに追加されたオブジェクトは自動的に管理されませんか? 2.最初から最後までcircularBufferから読み込みたい場合は、特にバッファが最初に満たされる前に、ヘッド変数なしでどのように行うのでしょうか? 3. circularBufferを空にする最も効率的な方法は何でしょうか? – philipfc

+0

更新された答えはかなり良いようです。ホットスポットがバッファ内容を読み取るように見えます。循環バッファがループしたら、新しい配列に循環バッファをコピーする必要がないように、列挙子(可能であれば高速列挙子)を使用する方が良いでしょうか? – philipfc

+0

列挙子の使用がより速くなることは疑いがあります。ポインタの範囲をコピーするだけだからです。 100%とは言えませんでした。 – norders

関連する問題