0
votes

If I need to create a large number of queues (say 10+ queues for image loading), is it faster to use the global concurrent queue or create the same number of private dispatch queues? For a quad-core CPU, is the concurrent queue limited to four concurrent queues before it turns into serial queue for subsequent queued tasks?

2
FYI - before posting more questions you should go back to some of your more recent questions and see if you should up vote or accept some of the answers. You haven't accepted any answer in several of your last few questions. Accepting an answer closes out the question and helps your reputation. - rmaddy

2 Answers

1
votes

I'd suggest creating your own concurrent queue which constrains how many concurrent operations are permitted. For example, you could create a single concurrent NSOperationQueue with maxConcurrentOperationCount set to four or five. Then add all of your synchronous image retrieval requests to that. For example:

NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 5;

Then just add all of your image requests with something like:

[queue addOperationWithBlock:^{
    // request image
}];

You can get fancier than that, but this is what a basic alternative to your two suggestions. But this will ensure that you do not have more than five concurrent network requests.

Note, for this to work (as well as your GCD suggestions), your operations, themselves, must be synchronous. If they are not synchronous, then you have to do some extra work to make sure that the operations don't complete until the task they perform does.


If you want to know when they're all done, you can use a completion operation:

NSOperation *completionOperation = [NSBlockOperation operationWithBlock:^{
    // this is what will happen when they're done
}];

Then add your operations:

NSOperation *operation = [NSBlockOperation operationWithBlock:^{
    // do network request here
}];

[completionOperation addDependency:operation];

[queue addOperation:operation];

And when done queuing all of your individual operations, you can then queue that completion operation, which won't fire until the rest are done (because you've declared a dependency between them):

[queue addOperation:completionOperation];
0
votes

Faster depends on the work being done, of course.

The global concurrent queue attempts to match the number of concurrent activities to the available hardware. That's not documented, so it might or might not match the number of cores (or maybe double the number of cores if they're hyper threaded and the work permits). If queued actions block (e.g. on network activity or disk I/O) then the global queue will start new jobs.

You can create your own queues to force the issue, but that probably won't help. If you have four cores then queueing up 10 or 20 or whatever number of simultaneous CPU-heavy actions isn't going to help the overall speed. Once you max out resources, you've maxed them out, and adding more private queues don't change that.