- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
时不时地,我注意到我正在使用一个 block 来迭代一个集合,而不写入任何共享数据或导致任何副作用。我考虑添加一个 NSEnumerationConcurrent 选项,然后决定反对它,因为我真的不明白什么时候值得使用它。
所以我有一个具体的问题,还有一个更一般的问题。
第一个问题:这里有一个可能有点做作的例子,使用 block 来同时做一些微不足道的事情:
CGFloat GetAverageHeight(NSArray* people)
{
NSUInteger count = [people count];
CGFloat* heights = malloc(sizeof(CGFloat) * count);
[people enumerateObjectsWithOptions: NSEnumerationConcurrent usingBlock:
^(id person, NSUInteger idx, BOOL* stop)
{
heights[idx] = [person height];
}];
CGFloat total= 0.0;
for (size_t i = 0 ; i < count ; i++) total += heights[i];
free(heights);
return total / count;
}
忽略非并发枚举可以直接对高度求和的事实,而不需要调用 malloc 或函数的后半部分,在这里使用 NSEnumerationConcurrent 有什么意义吗?使用 GCD 的开销(或 NSEnumerationConcurrent 在后台所做的任何事情)是否抵消了同时获得一个微不足道的属性的好处?在值得使用 NSEnumerationConcurrent 之前,该 block 的工作需要减少多少?
第二个问题:更一般地说,当我看到有机会这样做时,我是否应该考虑并发性是我应该使用的东西(理由:这些 API 的要点大概是它们使并发性不再是特例,而更多地成为程序的一般构成),或者仅当我发现特定的性能问题并相信并发是答案时才应该使用的优化(基本原理:并发代码中的错误是追查的噩梦)?
最佳答案
通常,只有在要执行的操作相对“繁重”时才使用并发。即便如此,如果并行度对于手头的任务而言是错误的粒度,那么使用 enumerateObjectsWithOptions:
提供的原始并发性也很容易出现问题。
GCD 在排队和处理东西方面确实非常高效,但该代码很可能最终会调用 malloc() 来复制 block (取决于 block 是否具有唯一的捕获状态)。
你的第二个问题的答案写满了很多书,大部分都没用。
采用非并发代码并使其并发通常是一个非常困难的问题,充满了噩梦般的错误。然而,预先设计并发性可能会非常耗时。更糟糕的是,在没有实际使用的情况下实现 future 的并发只会在您打开它时导致噩梦般的调试体验。
一个关键点;在考虑并发性时,专注于使对象的整个子图线程隔离,以保存跨越线程/队列的定义非常明确的边界 API。核心数据就是一个很好的例子。
关于objective-c - 何时使用 NSEnumerationConcurrent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6806930/
如果在使用 block 枚举集合时使用NSEnumerationConcurrent,Cocoa是否保证该 block 将同时执行?或者它实际上取决于需要枚举的对象的数量?另外,当操作实际上是并发的时
时不时地,我注意到我正在使用一个 block 来迭代一个集合,而不写入任何共享数据或导致任何副作用。我考虑添加一个 NSEnumerationConcurrent 选项,然后决定反对它,因为我真的不明
我有一本字典,第二本字典有 1000 个条目。这些条目都是类型为 key = key XXX 和 value = element XXX 的 NSString,其中 XXX 是介于 0 和元素数量之间
我是一名优秀的程序员,十分优秀!