目标c – GCD表现不佳
你可能记得,我试图使用GCD来加快我的一些代码,即碰撞检测和解析引擎.但是,我显然做错了,因为我的所有GCD代码都比我的序列号慢得多(1.4x和10x之间).请允许我举个例子:我以气泡排序的方式迭代数组,以确定该数组中对象之间的所有可能的冲突:
- (double) detectCollisionsInArray:(NSArray*)objects { int count = [objects count]; if (count > 0) { double time = CFAbsoluteTimeGetCurrent(); for (int i = 0; i < count; i++) { for (int j = i + 1; j < count; j++) { /** LOTS AND LOTS OF WORK FOR EACH OBJECT **/ } } return CFAbsoluteTimeGetCurrent() - time; } return 0; } 相当直截了当,考虑到问题的限制,它似乎表现良好.但是,我想利用每个对象的状态在代码段中不被修改,并使用GCD来并行化这个工作.为此,我正在尝试这样的事情: - (double) detectCollisionsInArray:(NSArray*)objects { int count = [objects count]; if (count > 0) { NSOperationQueue* opQueue = [[NSOperationQueue alloc] init]; NSBlockOperation* blockOperation = nil; double time = CFAbsoluteTimeGetCurrent(); for (int i = 0; i < count; i++) { for (int j = i + 1; j < count; j++) { void (^workBlock) (void) = ^() { /** LOTS AND LOTS OF WORK FOR EACH OBJECT **/ }; if (!blockOperation) { blockOperation = [NSBlockOperation blockOperationWithBlock:b]; } else { [blockOperation addExecutionBlock:workBlock]; } } } [opQueue addOperation:blockOperation]; [opQueue autorelease]; return CFAbsoluteTimeGetCurrent() - time; } return 0; } 任何人都可以帮助我走上正确的轨道,或者提供一个良好的GCD教程的链接?我已经浏览了几个GCD教程,并扫描了所有的文档,我仍然觉得我对这个问题的掌握至关重要.谢谢! 解决方法
有没有理由不使用GCD C API和dispatch_ *系列函数?您对NSOperationQueue的GCD方面没有太多的控制(比如要提交块的队列).另外,我不知道你是否使用iOS,但NSOperationQueue在iOS上并没有使用GCD.这可能是它产生了这么多线程的原因.无论哪种方式,如果直接使用GCD API,您的代码将会更简单和简单:
- (double) detectCollisionsInArray:(NSArray*)objects { int count = [objects count]; if (count > 0) { double time = CFAbsoluteTimeGetCurrent(); dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0); for (int i = 0; i < count; i++) { dispatch_group_async(group,queue,^{ for (int j = i + 1; j < count; j++) { dispatch_group_async(group,^{ /** LOTS AND LOTS OF WORK FOR EACH OBJECT **/ }); } }); } dispatch_group_wait(group,DISPATCH_TIME_FOREVER); dispatch_release(group); return CFAbsoluteTimeGetCurrent() - time; } return 0; } 您可以使用dispatch_group将所有执行组合在一起,并等待所有执行完成dispatch_group_wait.如果您不想知道块的完成情况,您可以忽略组件部分,只需使用dispatch_async. dispatch_get_global_queue函数将获得3个并发队列之一(低,默认或高优先级),以便将块提交到.你不必担心限制线程数或任何类似的事情. GCD调度程序应该为你做所有这些.只要确保提交到一个并发队列,它可以是3个全局队列之一,或者通过将DISPATCH_QUEUE_CONCURRENT传递给dispatch_queue_create创建的队列(这可以从OS X 10.7和iOS 5.0开始). 如果您在每个块中执行一些文件I / O或对某些其他资源征税,则可能需要在GCD中进行统计,并一次限制要提交到队列的块数.这将与限制NSOperationQueue中的并发操作计数具有相同的效果.您可以使用GCD信号量来做到这一点: - (double) detectCollisionsInArray:(NSArray*)objects { int count = [objects count]; if (count > 0) { double time = CFAbsoluteTimeGetCurrent(); dispatch_group_t group = dispatch_group_create(); dispatch_semaphore_t semaphore = dispatch_semaphore_create(10); dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0); for (int i = 0; i < count; i++) { dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER); dispatch_group_async(group,^{ for (int j = i + 1; j < count; j++) { dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER); dispatch_group_async(group,^{ /** LOTS AND LOTS OF WORK FOR EACH OBJECT **/ dispatch_semaphore_signal(semaphore); }); } dispatch_semaphore_signal(semaphore); }); } dispatch_group_wait(group,DISPATCH_TIME_FOREVER); dispatch_release(group); dispatch_release(semaphore); return CFAbsoluteTimeGetCurrent() - time; } return 0; } 一旦你得到它的悬挂,GCD是非常简单的使用.我现在使用它在我的代码.
运行,不要走到Mike Ash’s blog.他的GCD系列是我看到的最清晰和最简洁的,只需要你大约30分钟来阅读整个事情.苹果的WWDC视频从2010年的GCD和块也不错. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |