cocoa - NSMutableArray initWithCapacity matices
performance (2)
Si un espacio se desperdicia dando una capacidad demasiado grande es en realidad un detalle de implementación que Apple deliberadamente no expone, supongo. NSMutableArray es un clúster de clase, lo que significa que en realidad no se obtiene una instancia de NSMutableArray sino otra clase especializada siguiendo la misma interfaz. Y Apple no te dice qué clase devuelve en qué caso y cómo se comporta. Entonces es difícil dar consejos reales aquí.
Si realmente sabes que, en promedio, necesitarás una capacidad de X , solo úsala. De lo contrario, a menos que tengas problemas de rendimiento, no me importaría la capacidad y solo [NSMutableArray array]
...
¿Alguien tiene consejos sobre cómo inicializar mejor un NSMutableArray a la hora de dictar la capacidad? La documentación menciona que "... aunque especifique un tamaño cuando crea una matriz, el tamaño especificado se considera como una" pista ", el tamaño real de la matriz sigue siendo 0." Asi que...
1) Si inicio con una capacidad mayor a la que suelo usar, ¿no tengo que preocuparme por la pérdida de memoria?
2) Si inicio con una capacidad típicamente inferior a la que uso, ¿tengo que preocuparme por un mayor tiempo de procesamiento asignando más memoria para contener los elementos adicionales?
¿Qué tan impactante es esta capacidad inicializada para el uso de rendimiento / memoria de este tipo de datos?
Matt Gallagher ha escrito un artículo bastante informativo sobre las clases de colección de Cocoa, junto con un par de puntos de referencia (con & sin initWithCapacity:
, así como también comparaciones entre clases)
http://cocoawithlove.com/2008/08/nsarray-or-nsset-nsdictionary-or.html
Su prueba (fuente disponible) para un NSMutableArray de longitud 1,000,000 tomó 0.582256sec sin capacidad y solo 0.572139sec con capacidad .
Test | Time [NSMutableArray array] | 0.582256 seconds [NSMutableArray arrayWithCapacity:1000000] | 0.572139 seconds Iterating contents | 0.004713 seconds
Diría que en el 99% de los casos de uso [NSMutableArray array]
está bien. Sin embargo, si conoce el tamaño real de la matriz resultante, no le hará daño usar [NSMutableArray arrayWithCapacity:]
tampoco.
Y luego está este artículo de Peter Ammon ( desarrollador del equipo AppKit / Foundation de Apple ) que presenta varios puntos de referencia interesantes:
http://ridiculousfish.com/blog/archives/2005/12/23/array/
Editar (12 de marzo de 2012):
Más información sobre el rendimiento de inicialización de matriz de http://darkdust.net/writings/objective-c/nsarray-enumeration-performance
[...] I [=> DarkDust] también quería saber si el rendimiento es diferente dependiendo de cómo se creó la matriz. Probé dos métodos diferentes:
- Cree una matriz en C que haga referencia a las instancias del objeto y cree la matriz usando
initWithObjects:count:
- Cree un
NSMutableArray
y luego agregue objetos usandoaddObject:
[...] hay una diferencia al asignar: el
initWithObjects:count:
es más rápido . Con una gran cantidad de objetos , esta diferencia puede ser significativa .
Editar (6 de marzo de 2014):
Más información sobre el rendimiento de la inicialización de la matriz en http://ciechanowski.me/blog/2014/03/05/exposing-nsmutablearray/ :
Asigne nuevas matrices con la capacidad inicial establecida en potencias consecutivas de dos:
for (int i = 0; i < 16; i++) { NSLog(@"%@", [[[NSMutableArray alloc] initWithCapacity:1 << i] explored_description]); }
Sorpresa sorpresa:
size: 2 // requested capacity: 1 size: 2 // requested capacity: 2 size: 4 // requested capacity: 4 size: 8 // requested capacity: 8 size: 16 // requested capacity: 16 size: 16 // requested capacity: 32 size: 16 // requested capacity: 64 size: 16 // requested capacity: 128 ... // ''size: 16'' all the way down