Время от времени я замечаю, что я использую блок для итерации по коллекции без записи каких-либо общих данных или возникновения каких-либо побочных эффектов. Я рассматриваю возможность добавления в опцию NSEnumerationConcurrent, а затем решаю против нее, поскольку я не совсем понимаю, когда она стоит использовать.
Итак, у меня есть конкретный вопрос и более общий.
Первый вопрос: вот, может быть, немного надуманный пример использования блока для выполнения чего-то тривиального одновременно:
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?
Второй вопрос: в общем, следует ли считать concurrency тем, что я должен использовать, когда вижу возможность сделать это (логическое обоснование: предположительно, точка этих API-интерфейсов заключается в том, что они уменьшают concurrency от частного случая и большую часть общей составляющей программы), или просто оптимизацию, которую я должен использовать, только если я нашел конкретную проблему с производительностью и считаю, что concurrency является ответом (логическое обоснование: ошибки в параллельном коде - это кошмар для отслеживать)?