Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cocoa NSArray/NSSet: -makeObjectsPerformSelector: vs. fast enumeration

I want to perform the same action over several objects stored in a NSSet.

My first attempt was using a fast enumeration:

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

which works pretty fine. Then I thought of:

[mySetOfObjects makeObjectsPerformSelector:@selector(action)];

And now, I don't know what is the best choice. As far as I understand, the two solutions are equivalent. But are there arguments for preferring one solution over the other?

like image 973
mouviciel Avatar asked Feb 24 '09 16:02

mouviciel


People also ask

Which is faster to iterate through an NSArray or a NSSet?

Yes, NSArray is faster than NSSet for simply holding and iterating. As little as 50% faster for constructing and as much as 500% faster for iterating.

What's a difference between NSArray and NSSet?

The main difference is that NSArray is for an ordered collection and NSSet is for an unordered collection. There are several articles out there that talk about the difference in speed between the two, like this one. If you're iterating through an unordered collection, NSSet is great.

What is fast enumeration?

Fast enumeration is a language feature that allows you to efficiently and safely enumerate over the contents of a collection using a concise syntax.

What is fast enumeration in Objective C?

Fast Enumeration was introduced into Objective-C back in the 10.5 days. It's the feature that lets you succinctly iterate through a collection: NSArray *strings = [NSArray arrayWithObjects: @"greeble", @"bork", @"hoover", nil]; for (NSString *thing in strings) { NSLog (@"Woo!


2 Answers

I would argue for using makeObjectsPerformSelector, since it allows the NSSet object to take care of its own indexing, looping and message dispatching. The people who wrote the NSSet code are most likely to know the best way to implement that particular loop.

At worst, they would simply implement the exact same loop, and all you gain is slightly cleaner code (no need for the enclosing loop). At best, they made some internal optimizations and the code will actually run faster.

The topic is briefly mentioned in Apple's Code Speed Performance document, in the section titled "Unrolling Loops".

If you're concerned about performance, the best thing to do is set up a quick program which performs some selector on the objects in a set. Have it run several million times, and time the difference between the two different cases.

like image 138
e.James Avatar answered Sep 20 '22 03:09

e.James


I too was presented with this question. I find in the Apple docs "Collections Programming Topics" under "Sets: Unordered Collections of Objects" the following:

The NSSet method objectEnumerator lets you traverse elements of the set one by one. And themakeObjectsPerformSelector: and makeObjectsPerformSelector:withObject: methods provide for sending messages to individual objects in the set. In most cases, fast enumeration should be used because it is faster and more flexible than using an NSEnumerator or the makeObjectsPerformSelector: method. For more on enumeration, see “Enumeration: Traversing a Collection’s Elements.”

This leads me to believe that Fast Enumeration is still the most efficient means for this application.

like image 28
daveMac Avatar answered Sep 18 '22 03:09

daveMac