2009-02-24 3 views
13

NSSet에 저장된 여러 개체에 대해 동일한 작업을 수행하고 싶습니다. 꽤 잘 작동코코아 NSArray/NSSet : -makeObjectsPerformSelector : 빠른 열거 형 대

for (id item in mySetOfObjects) 
    [item action]; 

:

내 첫 번째 시도는 빠른 열거를 사용하고 있었다. 그럼 내가 생각한 :

[mySetOfObjects makeObjectsPerformSelector:@selector(action)]; 

그리고 지금, 나는 최선의 선택을 모른다. 내가 아는 한, 두 가지 해결책은 동일합니다. 그러나 한 솔루션을 다른 솔루션보다 선호하는 것에 대한 논쟁이 있습니까?

답변

21

makeObjectsPerformSelector은 NSSet 객체가 자체 인덱싱, 루핑 및 메시지 전달을 처리 할 수 ​​있기 때문에 논쟁이됩니다. NSSet 코드를 작성한 사람들은 특정 루프를 구현하는 가장 좋은 방법을 가장 잘 알고 있습니다.

최악의 경우, 그들은 똑같은 루프를 구현하기 만하면되는 모든 코드는 약간 깔끔한 코드입니다 (둘러싸는 루프는 필요 없습니다). 기껏해야 내부 최적화를 수행했으며 코드가 실제로 더 빠르게 실행됩니다.

주제는 Apple의 Code Speed Performance 문서의 "Unrolling Loops"절에서 간략하게 언급됩니다.

성능에 대해 염려가되는 경우 가장 좋은 방법은 세트의 개체에 대한 선택기를 수행하는 빠른 프로그램을 설정하는 것입니다. 수백만 번 실행하고 두 가지 다른 경우의 차이를 시간을 잰다.

+0

링크를 가져 주셔서 감사합니다.이 문서를 알지 못했습니다! Cocoa 개발자가 -makeObjectsPerformSelector : – mouviciel

+0

을 사용하여 내부 최적화를 수행했다는 것을 명확하게 설명합니다. 거기에 흥미로운 것들이 있습니다. –

2

makeObjectsPerformSelector: 다소 빠르지 만 실제로는 99 %의 차이가있을 수 있습니다. 좀 더 간결하고 읽기 쉽지만, 나는 그 이유 때문에 그것을 사용할 것입니다.

4

나는 자주 보지 않는 종류의 전화라는 간단한 이유 때문에 makeObjectsPerformSelector를 사용하지 않을 것입니다. 다음은 예를 들어 이유입니다 - 배열이 열거 될 때 디버깅 코드를 추가해야합니다. 실제로 코드가 해제 모드에서 작동하는 방식을 변경하지 않으면 makeObjectsPerformSelector를 사용하여 실제로 그렇게 할 수 없습니다.

for (id item in mySetOfObjects) 
{ 
    #if MY_DEBUG_BUILD 
    if ([item isAllMessedUp]) 
     NSLog(@"we found that wily bug that has been haunting us"); 
    #endif 

    [item action]; 
} 

--Tom

7

나도이 질문되게되었다. 나는 다음과 같은 "Sets: Unordered Collections of Objects"에서 "컬렉션이 항목을 프로그래밍"애플의 문서에서 찾을 수 있습니다 : 당신이 설정 한 하나 의 요소를 통과

NSSet 방법 objectEnumerator가 있습니다. themakeObjectsPerformSelector : 및 makeObjectsPerformSelector : withObject : 메서드는 집합에있는 개별 객체에 메시지를 보내도록 제공합니다. 대부분의 경우 빠른 열거 형은 NSEnumerator 또는 makeObjectsPerformSelector : 메서드를 사용하는 것보다 더 빠르며 보다 유연하므로 이 사용되어야합니다. 열거 형에 대한 자세한 내용은 "열거 형 : 컬렉션 요소 전송을 참조하십시오."

이렇게하면 Fast Enumeration이 여전히이 애플리케이션을위한 가장 효율적인 수단이라고 믿습니다.

1

순수한 속도 만 문제가되는 경우 (예 : 모든 소형 CPU주기가 계산되는 렌더링 엔진을 만드는 경우) NSCollection 개체를 반복하는 가장 빠른 방법은 (iOS 5.0 ~ 6.0 기준)입니다. 다양한 "enumerateObjectsUsingBlock"메소드. 왜 이런지 모르겠지만 테스트를 거쳤습니다.이 경우에 해당하는 것 같습니다 ...

간단한 테스트를 작성하여 수십만 개의 개체 컬렉션을 만들었습니다. 각 개체에는 간단한 int 배열 . 이러한 컬렉션 각각은 수백만 회 반복 (for 루프, 빠른 열거, makeObjectsPerformSelector 및 enumerateObjectsUsingBlock)의 다양한 유형을 수행해야했으며 거의 ​​모든 경우에 "enumerateObjectsUsingBlock"메소드가 테스트 과정에서 편리하게 수상했습니다.

이것이 사실이 아니었던 유일한 때는 메모리가 가득 채워지기 시작한 때였습니다. (내가 수백만 개의 개체로 실행하기 시작했을 때) "makeObjectsPerformSelector"가 손실되기 시작했습니다.

죄송합니다. 코드의 스냅 샷을 찍지는 않았지만 실행하기에 매우 간단한 테스트입니다. 직접 시도해보고 직접 사용해보십시오. :)