views:

92

answers:

3

I have a method in my iPhone app that is very repetitive (called over and over and over sequentially). The method is quite bulky and takes about one second to complete.

My question is this: If I was to muti-thread it to run, say 5 method calls on different threads simultaneously, would that be any faster than running 5 calls one after another? I know of desktop machines with multi-core processors this would be an advantage, but I am not sure about the iPhone.

Any advice?

+2  A: 

Try it, there is no better answer. It’s not hard:

- (void) startInParallel {
    for (int i=0; i<5; i++)
        [self performSelectorInBackground:@selector(doSomeWork)];
}

Plus you might want to add some time measuring. Then, if you find out that running all the operations in parallel really makes sense, you can use NSOperations or GCD to do it. (I just hope that performSelectorInBackground does not have enough time cost to skew the test results.)

zoul
Exactly! The correct answer to a "which is faster?" question is almost always "profile it and see!"
Jeremy W. Sherman
+2  A: 

If it's something like a network request, it will most probably be faster because you're spending time waiting without really using the processor (although spawning threads is not really the best way to deal with that). But if the method is doing some heavy calculations you won't gain anything. Still, to keep the UI responsive you would run lengthy tasks in the background. It's usually better and simpler to use NSOperation for such things, so have a look at that class.

Felixyz
+2  A: 

Use Grand Central Dispatch (aka GCD and libdispatch) and it'll just Do The Right Thing(tm).

If you call dispatch_async on one of the global queues, GCD will figure depending on system workload whether to spawn new threads to handle the operations you submit, or whether to run them in series on one thread.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
     // Do your calculations here

     // If you want to run code on the main loop with the result of the calculations,
     // do something like this
     dispatch_async(dispatch_get_main_queue(), ^{
         // Code to run on the main thread here
     });
});

You could also use dispatch groups to run some code after all five calls have completed.

Take a look at the Concurrency Programming Guide and the GCD reference manual for details.

Update

Also look at this article from Ars on GCD. They explain some of the details of how GCD decides how to schedule blocks.

Jacques
The question is whether it is faster to run the operations in succession or in parallel. That IMHO depends on the nature of the operations and I don't see how GCD could make the right decision here. Or can it?
zoul
It can take a very good guess, which will be more likely to be correct than your guess is. Plus, it choose the middle ground between "one thread per operation" and "all operations on one thread". It's actually pretty easy to imagine simple heuristics that would do a decent job: If there are no threads that are ready to run, but there are blocks waiting to be executed, spawn a new thread to start handling blocks. If there are many threads contending for the CPU, kill a few. Of course, I'm sure there are a lot of extra details to make it work in the real world, but the concept is pretty simple.
Jacques
But *you don’t have to guess if you can profile*. The poster says that one run takes about a second. That means the operation is quite deterministic and you can tell which scenario comes out better in this case. Quite probably you would implement the result using GCD, but it’s good to know which one of the serial/parallel cases you are striving for.
zoul