De vez en cuando, veo que estoy usando un bloque para iterar sobre una colección sin escribir en ningún dato compartido ni causar ningún efecto secundario. Considero agregar una opción NSEnumerationConcurrent, luego decido no hacerlo ya que realmente no entiendo cuándo vale la pena usarla.Cuándo utilizar NSEnumerationConcurrent
Así que tengo una pregunta específica, y una más general.
Primera pregunta: He aquí un ejemplo tal vez un poco artificiosa de la utilización de un bloque de hacer algo trivial simultáneamente:
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;
}
Ignorando el hecho de que una enumeración no concurrente podría haber simplemente resumió la altura directamente, sin la necesidad para llamar a malloc o la segunda mitad de la función, ¿hay algún punto usando NSEnumerationConcurrent aquí? ¿Niega la sobrecarga de usar GCD (o lo que sea que haga NSEnumerationConcurrent en el fondo) negar la ganancia de obtener una propiedad trivial al mismo tiempo? ¿Cuánto menos trivial necesita el trabajo del bloque antes de que valga la pena usar NSEnumerationConcurrent?
Segunda pregunta: más en general, ¿debería considerar la concurrencia como algo que debería usar cuando veo la oportunidad de hacerlo (justificación: presumiblemente el objetivo de estas API es que hacen que la concurrencia sea menos un caso especial y más parte de la configuración general de un programa), o simplemente una optimización que solo debería usar si encuentro un problema de rendimiento específico y creo que la concurrencia es la respuesta (razón de ser: los errores en el código simultáneo son una pesadilla para rastrear).