1

I thought iterating through Blocks is faster than enumeration and in some case it does. However with this simple example where I have a data array and I am creating multiple arrays using different iterating approaches and the results are not something that I was expecting.

An explanation would he helpful.

NSMutableArray *dataArray =[[[NSMutableArray alloc] init] autorelease];
NSMutableArray *mArray1 = [[[NSMutableArray alloc] init] autorelease];
NSMutableArray *mArray2 = [[[NSMutableArray alloc] init] autorelease];
NSMutableArray *mArray3 = [[[NSMutableArray alloc] init] autorelease];

NSDate *dt1 = [NSDate date];
for (int j=0; j<10000000;j++)
{
    [dataArray addObject:[NSNumber numberWithInt:j]];
}

NSDate *dt2 = [NSDate date];
int cnt = [dataArray count];
//Using normal for loop
for (int k=0; k<cnt;k++)
{
    [mArray1 addObject:[dataArray objectAtIndex:k]];
}

//Using Fast Enumeration
NSDate *dt3 = [NSDate date];
for (NSNumber *num in dataArray)
{
    [mArray2 addObject:num];
}


//Enumerating using Blocks
NSDate *dt4 = [NSDate date];
[dataArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    [mArray3 addObject:obj];
}];
NSDate *dt5 = [NSDate date];

NSLog(@"Time taken to create the data array %f",[dt2 timeIntervalSinceDate:dt1]);
NSLog(@"Time taken to iterate using normal for loop %f",[dt3 timeIntervalSinceDate:dt2]);
NSLog(@"Time taken to iterate using fast enumeration %f",[dt4 timeIntervalSinceDate:dt3]);
NSLog(@"Time taken to iterate using blocks %f",[dt5 timeIntervalSinceDate:dt4]);

//Time taken to create the data array 0.383750

//Time taken to iterate using normal for loop 0.309719

//Time taken to iterate using fast enumeration 0.278467

//Time taken to iterate using blocks 0.526629

Debasis Das
  • 102
  • 7
  • That "fast enumeration" is faster than "block enumeration" was also reported here: http://blog.bignerdranch.com/2337-incremental-arrayification/ – Martin R Apr 22 '14 at 18:35
  • 1
    Did you run the tests hundreds of times to get an average? What about running them in a different order? Each test uses up a bunch of memory. – rmaddy Apr 22 '14 at 19:24
  • If you care about performance at this level, Objective-C isn't the right language. IMO, it's fairly fast. If you need a faster approach you should use C++. And, btw. your measurements show (in relation) what is to be expected. – CouchDeveloper Apr 22 '14 at 19:33

3 Answers3

1

There's a really good post by NSHipster (@mattt) about all the different enumerators. Take a read of that and it will explain all the differences.

Fast enumeration is faster, but you have the added benefit with block enumeration of having the object and its index which is useful!

Community
  • 1
  • 1
Rich
  • 8,108
  • 5
  • 46
  • 59
  • Extract from NSHipster@matt . Unless you actually need the numerical index while iterating, it's almost always faster to use a for/in NSFastEnumeration loop instead. – Debasis Das Apr 22 '14 at 18:47
  • Yeah, I didn't not say that :) It all depends on your use case, if you've got a few items and want the index its useful then! – Rich Apr 22 '14 at 18:50
0

The only reason I could see without analyzing the generated assembly, is the following.

invoking a block has an overhead compared to the other loop methods.

Also you can try enumerateObjectsWithOptions:NSEnumerationConcurrent instead, in practice it can be faster than the fast loop since it can be parallelized.

Keep in mind that if wont be faster if you use synchronized stuff inside the block(not sure if NSArray is synchronized or not though)

Sangram Shivankar
  • 3,535
  • 3
  • 26
  • 38
gimpycpu
  • 607
  • 6
  • 16
0

Like gimpycpu said, using block's concurrent enumeration is where you will see the performance impact of enumerating with blocks. Utilizing GCD and enumerating across various threads (on thread safe data sets) will probably be what you were hoping for.

Sample Enumerations

Graphs / Explanations : Results

Testing / Code Samples : Code


If concurrency is an issue, consider attempting a binary search for a considerable performance boost.

  • Requires a sorted NSArray.
ChrisHaze
  • 2,800
  • 16
  • 20