Pregunta

I need to process a large amount of data from a NSDictionary into NSManagedObjects (3k-10k objects).

With synchronous processing, 3k takes about 60 seconds:

for (NSString *key in myDictionary) {
    //process data
}

When I use GCD and create a new thread for each key, it takes about 20 seconds and used a bunch of threads:

for (NSString *key in myDictionary) {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //process data
    }
}      

Then I tried using NSOperationQueue with NSBLockOperation and for each key, adding a block execution which took about 30 seconds and only used 2 threads:

NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSBlockOperation *operation = [[NSBlockOperation alloc] init];

for (NSString *key in myDictionary) {
    [operation addExecutionBlock:^{
    // processs data
    }
}

[operation setCompletionBlock:^{
    DLog(@"Block completed | time: %f", [[NSDate date] timeIntervalSinceDate:startTime]);
}];

[queue addOperation:operation];

This gives the advantage of having a completion block.

In terms of speed, a thread per key seems to be the quickest.

All times where done on a device, not simulator.

I've read when considering NSOperation vs GCD, they suggest using the higher level API which is the NSOperation, but the GCD gives better performance.

Is there any advantage to using the NSOperationQueue and NSBlockOperation other then the completion block? Or am I missing something that makes the queue and blocks inherently better then GCD?

¿Fue útil?

Solución

Or am I missing something that makes the queue and blocks inherently better then GCD?

You're not missing anything -- operations are implemented using GCD. As you've seen, it can be nice to have a higher-level API than just straight GCD, but in the end operations aren't inherently different from using GCD.

Otros consejos

As mentioned operations and operations queues are built on top of GCD. But there are some differences:

  • Operation queues can have a width. GCD knows serial or concurrent queues only.
  • Operation queues can handle dependencies.
  • Operations can have a priority (added)
  • GCD can handle "run loop stuff" (system events)

As mentioned in my comment your GCD code uses only one thread:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    for (NSString *key in myDictionary) {
        //process data
    }  
}

Try this and report the result, please:

for (NSString *key in myDictionary) {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //process data
    }  
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top