Re: [__NSFastEnumerationEnumerator nextObject] unexpectedly not very fast!
Re: [__NSFastEnumerationEnumerator nextObject] unexpectedly not very fast!
- Subject: Re: [__NSFastEnumerationEnumerator nextObject] unexpectedly not very fast!
- From: Charles Srstka <email@hidden>
- Date: Fri, 25 Sep 2009 19:29:32 -0500
On Sep 25, 2009, at 12:38 PM, Ben Trumbull wrote:
In summary, the existence of fast enumeration does nothing for
existing enumeration technologies and if you have to support
10.4 (as I do) you simply can't use it unless you fork your code.
My solution, in the few cases where performance is paramount,
has been to essentially roll my own fast enumeration. For very
large arrays (thousands of objects) I'll get blocks of objects
in batching using [NSArray getObjects:range:], process those in
a tight C loop, and then get another batch.
The for (in) construct is by far the most optimized general purpose
way to work with any of the collections in Cocoa on 10.5, 10.6, and
iPhone OS. It's also polymorphic, so custom collection subclasses
can fine tune the behavior.
If you have to hand roll your own, either for 10.4, or some
specialized case, your best bet is to use -getObjects: into a local
buffer. gcc supports variable length arrays, and that's the fastest
way to marshall these batches temporarily. You'll want to be very
careful to do length checks to not overrun your stack, and limit the
size. If you have somewhere between 256 & 512 objects, give or
take, you'll have to malloc a temporary id* Overflowing the stack
is not pretty.
What I did was to create a "CSForeach" set of macros which take a
variable and a collection name, with #ifdefs set up to cause different
macros to be used under 32-bit and 64-bit. Under 64-bit, it's pretty
safe to assume the user is running Leopard or better, so the macro
evaluates to for(var in collection), but in 32-bit, it makes an
enumerator and generates a while loop. This way, most people running
Leopard on relatively recent hardware will get the faster enumeration,
and those running 10.4 will at least have it still work.
I also made a conditional version of the macro, which lets me specify
a condition to check each time the loop comes around. In 32-bit, it
changes the while loop to while((foo = [enumerator nextObject]) &&
bar), whereas in 64-bit it adds a if(!bar) break; at the beginning of
the loop.
Charles
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden