本文介绍了何时使用NSEnumerationConcurrent的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

无论何时,我注意到我使用一个块来迭代集合,而不写入任何共享数据或导致任何副作用。我考虑添加一个NSEnumerationConcurrent选项,然后决定它,因为我不真正明白什么时候值得使用。

Every now and then, I notice that I'm using a block to iterate over a collection without writing to any shared data or causing any side effects. I consider adding in an NSEnumerationConcurrent option, then decide against it as I don't really understand when it's worth using.

所以我有一个具体的问题,更常见的一个。

So I've got a specific question, and a more general one.

第一个问题:这里有一个使用块做并行处理的例子:

First question: Here's a maybe slightly contrived example of using a block to do something trivial concurrently:

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在后台)的开销取消了同时获得一个平凡属性的收益?

Ignoring the fact that a non-concurrent enumeration could have just summed the height directly, without the need for calling malloc or the second half of the function, is there any point using NSEnumerationConcurrent here? Does the overhead of using GCD (or whatever NSEnumerationConcurrent does in the background) negate the gain of getting a trivial property concurrently? How much less trivial does the block's work need to get before it's worth using NSEnumerationConcurrent?

第二个问题:更广泛地说,我应该考虑并发性是我应该使用的东西,当我使用NSEnumerationConcurrent看到一个机会这样做(理由:据推测,这些API的要点是他们使并发少一个特殊情况和更多的一部分的程序的一般组成),或者只是一个优化,我应该使用,如果我发现了一个具体的性能问题,并认为并发是答案(理由:并发代码中的错误是一个噩梦跟踪)。

Second question: More generally, should I consider concurrency to be something I should use when I see an opportunity to do so (rationale: presumably the point of these APIs is that they make concurrency less of a special case and more part of the general makeup of a program), or just an optimisation that I should only use if I've found a specific performance issue and believe that concurrency is the answer (rationale: bugs in concurrent code are a nightmare to track down)?

推荐答案

p>通常,只有当要执行的操作相对重时才使用并发。即使如此,如果并行性对于手头的任务来说是错误的粒度,使用 enumerateObjectsWithOptions:提供的原始并发很容易出现问题。

Generally, you'd only use concurrency when the operations to be performed are relatively "heavy". Even then, using the raw concurrency offered by enumerateObjectsWithOptions: could easily be problematic if the parallelism is the wrong granularity for the task at hand.

GCD在排队和处理内容时效率非常高,但是该代码很可能最终会调用malloc()来复制块(取决于块是否具有唯一捕获状态)。

GCD is really damned efficient at enqueuing and processing stuff, but that code is quite likely going to end up calling malloc() to copy the block (depends on whether the block has unique captured state).

第二个问题的答案填充了很多书,最无用的。

The answer to your second question fills many books, most useless.

取非并发代码并使其并发一般是一个非常困难的问题与夜恶魔的bug。然而,前面的并发设计可能非常耗时。更糟糕的是,在未实际使用它的情况下实现未来并发只会导致一个噩梦的调试体验。

Taking non-concurrent code and making it concurrent is generally a Very Hard Problem rife with nightmarish bugs. Yet, designing for concurrency up front can be exceptionally time consuming. Worse, implementing for future concurrency without actually using it just leads to a nightmarish debugging experience when you do turn it on.

一个关键点;当考虑并发性时,专注于整个线程隔离对象的子图形保存跨越线程/队列的非常好的定义的边界API。一个很好的例子是Core Data。

One key point; when considering concurrency, focus on making entire sub-graphs of objects thread-isolated save for exceedingly well defined boundary API that spans threads/queues. A good example of this is Core Data.

这篇关于何时使用NSEnumerationConcurrent的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-19 00:59