0

Objective C의 순환 버퍼에 두 배의 배열을 초당 여러 번 추가하려고합니다.고성능을 위해 Objective C에서 순환 버퍼를 구현하는 방법

현재 다른 NSMutableArray (2D 배열) 내에 중첩 된 NSMutableArray를 사용하고 있습니다. 이것은 잘 작동하지만 우리의 필요에 비해 너무 느립니다.

우리는 순환 버퍼에 여러 번 추가하려고합니다. 이를 수행하고 성능 모니터링을 수행 할 때 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에서 읽으려는 경우, 특히 버퍼가 처음 채워지기 전에 head 변수없이 어떻게 처리 할 수 ​​있습니까? 3. circularBuffer를 비우는 가장 효율적인 방법은 무엇입니까? – philipfc

+0

업데이트 된 대답은 꽤 좋은 것처럼 보입니다. 핫스팟이 버퍼 내용을 읽는 것처럼 보입니다. 열거 자 (가능하면 빠른 열거 자)를 사용하여 버퍼가 반복되면 순환 버퍼를 새 배열에 복사 할 필요가 없으므로 더 좋을까요? – philipfc

+0

열거자를 사용하는 것이 포인터 범위 만 복사하므로 더 빠를 것이라고 생각하지 않습니다. 100 %라고 말할 수는 없습니다. – norders