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.
for (id obj in array) { /* Do something with |obj|. */ }
[array enumerateObjectsUsingBlock: ^(id obj, NSUInteger idx, BOOL *stop) { /* Do something with |obj|. */ }];
[array enumerateObjectsWithOptions: NSEnumerationConcurrent usingBlock: ^(id obj, NSUInteger idx, BOOL *stop) { /* Do something with |obj|. */ }];
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|. */ });
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 NSBlockOperation
s or an NSOperationQueue
?
TIA, Alex.
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!
Fast enumeration is a language feature that allows you to efficiently and safely enumerate over the contents of a collection using a concise syntax.
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.
It really depends on the task at hand.
Processing more than one iteration at a time requires spawning threads. If the logic in the iterations is parallelizable and takes more time than it would take to spawn a thread, then use threads. Also, if you have so many items in the array that it would take less to spawn a thread than to walk through the whole array, divide your array into a few pieces and process them in parallel.
Otherwise, spawning threads to iterate through the array is overhead. Even if the OS takes care of that for you, it still does need to spawn them. That takes time and resources and context switching at runtime (depending on the number of CPUs available, load, scheduler, etc).
It all comes down to whether spawning a new thread takes longer than walking through the whole array. You can find that out using the profiling tools.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With