Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How lightweight is NSOperationQueue on Snow Leopard?

I'm working with some code that does a bunch of asynchronous operating with various callbacks; Snow Leopard has made this incredibly easy with blocks and GCD.

I'm calling NSTask from an NSBlockOperation like so:

[self.queue addOperationWithBlock:^{
    NSTask *task = [NSTask new];
    NSPipe *newPipe = [NSPipe new];
    NSFileHandle *readHandle = [newPipe fileHandleForReading];
    NSData *inData = nil;
    [task setLaunchPath:path];
    [task setArguments:arguments];
    [task launch];

    while ((inData = [readHandle availableData]) && [inData length]) {
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            // callback
        }];
    }

    [task waitUntilExit];
}];

This approach works perfectly. It's like magic, as long as my callbacks handle the concurrency correctly.

Now, I want to be able to coalesce some of these calls; this is inside a model object's "refresh" method and may take a long time to complete. Having the user pound on the refresh button shouldn't tie up the machine and all that.

I can see an implementation dilemma here. I can make a whole bunch of queues - one per call type - and set their concurrent operation counts to 1 and then call -cancelAllOperations whenever it's time for a new call.

Alternately, I could do some more manual bookkeeping on which calls are currently happening and manage a single queue per model object (as I'm doing) or I could go even further and use a global queue.

How heavy is NSOperationQueue? Is creating a lot of queues a bad architecture decision? Is there a better way to coalesce these tasks?

like image 559
Jim Puls Avatar asked Oct 03 '09 07:10

Jim Puls


2 Answers

If you're concerned about performance, don't guess: measure and then fix any bottlenecks you find. Adding queues is simple; try it and see what Instruments tells you about the effect on performance.

The main reason for creating multiple queues is in case you have some reason for wanting to start and stop them. If you just want to get the benefits of libdispatch, you can get that by just adding operations to the main queue.

like image 199
NSResponder Avatar answered Sep 21 '22 01:09

NSResponder


You can add multiple blocks to an NSBlockOperation which will be executed concurrently and can be canceled by canceling the containing operation. As long as your individual tasks don't have to be serialized, this may work.

like image 37
Barry Wark Avatar answered Sep 19 '22 01:09

Barry Wark