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