Objective C — What is the fastest and most efficient way to enumerate an array?

Alexsander Akers picture Alexsander Akers · Jun 1, 2011 · Viewed 8.1k times · Source

Edit

I read through some articles on blocks and fast enumeration and GCD and the like. @Bbum, who's written many articles on the subject of GCD and blocks, says that the block enumeration methods are always as fast or faster than the fast enumeration equivalents. You can read his reasoning here.

While this has been a fascinating, intellectual conversation, I agree with those who said that it really depends on the task at hand.


I have some tasks to accomplish and I need them done fast, cheap, and efficiently. Apple gives us many choices for how we want to enumerate an array, but I'm not sure which to choose.

Fast Enumeration

for (id obj in array)
{
    /* Do something with |obj|. */
}

Nonconcurrent Block Enumeration

[array enumerateObjectsUsingBlock: ^(id obj, NSUInteger idx, BOOL *stop) {
    /* Do something with |obj|. */
}];

Concurrent Block Enumeration

[array enumerateObjectsWithOptions: NSEnumerationConcurrent usingBlock: ^(id obj, NSUInteger idx, BOOL *stop) {
    /* Do something with |obj|. */
}];

GCD Apply

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_apply([array count], queue, ^(size_t idx) {
    id obj = [array objectAtIndex: idx];
    /* Do something with |obj|. */
});

GCD Async Apply

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(queue, ^(void) {
    dispatch_apply([array count], queue, ^(size_t idx) {
        id obj = [array objectAtIndex: idx];
        /* Do something with |obj|. */
    });
});

Or perhaps something with NSBlockOperations or an NSOperationQueue?

TIA, Alex.

Answer

bbum picture bbum · Jun 1, 2011

The fastest code is the code that reaches the market first.

Seriously -- unless you have a measurable performance problem, this particular choice should occupy no more of your time than it takes to answer which of these patterns fits the most naturally with my project's style?

Note: adressing a performance problem by moving from serial to concurrent execution usually results having two problems; performance & concurrency.