2009-12-25 13 views
5

He estado desarrollando para el iPhone desde hace bastante tiempo y me he estado preguntando si hay algún objeto de matriz que utiliza un buffer circular en Obj-C? Como Pila o Lista o Cola de Java. He estado retocando con NSMutableArray, probando sus límites ... y parece que después de 50k objetos simples dentro de la matriz, la aplicación se ralentiza significativamente.obj-C circular buffer object, implementing one?

Entonces, ¿hay alguna otra solución mejor que NSMutableArray (que se vuelve muy lenta con grandes cantidades de datos). Si no, ¿alguien puede decirme sobre una manera de crear un objeto así (implicaría el uso de objetos de cadena (nodo) ??).

Conclusión: ¿Completar una UITableView desde una base de datos SQLite directamente sería inteligente? Como no requerirá memoria de una matriz ni nada, solo las consultas. Y SQLite es rápido y no tiene memoria.

Muchas gracias por su tiempo y atención, ~ Natanavra.


Por lo que he estado pensando, parece que ir a la clase de Quinn es la mejor opción posible. Tengo otra pregunta: ¿sería más rápido o más inteligente cargar todo directamente desde la base de datos SQLite en lugar de crear un objeto y colocarlo en una matriz?

Gracias de antemano, ~ Natanavra.

Respuesta

8

Disculpas por tocar mi propia bocina, pero implementé una memoria intermedia circular basada en C en CHDataStructures. (Específicamente, consulte CHCircularBufferQueue y CHCircularBufferStack). El proyecto es de código abierto y tiene puntos de referencia que demuestran que un buffer circular verdadero es bastante rápido en comparación con NSMutableArray en el caso general, pero los resultados dependerán de sus datos y uso, así como el hecho de que está operando en un dispositivo con memoria limitada (por ejemplo, iPhone). ¡Espero que ayude!

+0

Gracias! Eso suena como lo que estoy buscando ... aunque no es crítico, quiero encontrar una manera de poder mostrar 50k-100k de objetos fácilmente en una UITableView. – natanavra

+0

¿Alguno de los CHDataStructures permite crear un búfer circular FIFO real, sobrescribiendo los datos anteriores al sobrellenar el búfer? ¡Gracias! –

+1

Mi clase implementa un búfer en crecimiento dinámico, en lugar de un tamaño fijo, pero podría adaptarlo eliminando el código de ajuste de tamaño y agregando algunos cambios para liberar objetos antes de sobrescribirlos. Como uso esto para respaldar una cola, y no quiero sobreescribir datos, no había considerado este caso. No es una mala idea para una mejora futura ... –

-3

Objective-C objetos no son realmente "simples", por lo que 50,000 de ellos va a ser muy exigente. Escriba el suyo propio en C o C++ directo si desea evitar los cuellos de botella y las demandas de recursos del tiempo de ejecución de Objective-C. discusión

Una bastante largo y no teórico de la sobrecarga asociada con la conveniencia:

http://www.cocoabuilder.com/archive/cocoa/35145-nsarray-overhead-question.html#35128

Y un poco de matemática sencilla para la gente sencilla:

Todo lo que necesita para hacer un objeto como opuesto a una estructura es un solo puntero al comienzo.

Digamos que es cierto, y digamos que estamos corriendo en un sistema de 32 bits con punteros de 4 bytes.

4 bytes x 50.000 objetos = 200000 bytes

que es casi 200 MB de memoria equivalente extra que sus necesidades de datos de repente sólo porque que utilizó Objective-C. Ahora comprenda eso con el hecho de que sea lo que sea que NSArray agregue esos objetos a va a duplicar eso manteniendo su propio conjunto de punteros a esos objetos y que acaba de masticar 400MB de RAM solo para que pueda usar un par de conveniencia envoltorios.

Renueve mi memoria aquí ... ¿Los archivos de intercambio en los discos duros son tan rápidos como la memoria RAM? ¿Cuánta memoria RAM hay en un iPhone? ¿Cuántas llamadas de función y marcos de pila se necesitan para enviar un mensaje a un objeto? ¿Por qué no se escribe IOKit en Objective-C? ¿Cuántas de las principales aplicaciones de Apple que usan mucho DSP usan AppKit? ¿Alguien tiene una copia de otool con la que pueden consultar? Estoy viendo cero aquí.

+2

A menos que hayas probado y probado que tu solución C es más rápida, no haría eso. – Chuck

+0

Tendría que escribir un código bastante terrible para llegar a una implementación de la lista vinculada basada en C que sea más lenta que la cantidad de mensajes de Objective-C involucrados en mantener un NSArray. –

+1

Debe leer todo el hilo, incluido el mensaje de Chris Kane, antes de suponer alegremente que implementar su propia lista enlazada superará a NSArray. – NSResponder

1

Es trivial tener la matriz NSMutable actuando como una pila, lista, cola, etc. usando los diversos métodos insertObject:atIndex: y removeObjectAtIndex:. Puede escribir sus propias subclases si desea configurar el comportamiento.

Dudo que los problemas de rendimiento que está viendo sean causados ​​por NSMutableArray, especialmente si su punto de referencia es la Java mucho, mucho más lenta. El problema es muy probablemente el iPhone en sí. Como se señaló anteriormente, 50,000 objetos objetivo-c no es una cantidad trivial de datos en este contexto y el hardware del iPhone puede tener dificultades para manejar esa cantidad de datos.

Si necesita algún tipo de arreglo de alto rendimiento para bytes, puede usar uno de los arreglos principales de base o enrollar el suyo en C simple y luego envolverlos en una clase personalizada.

Me parece que necesita cambiar a los datos del núcleo para que no tenga que guardar todo esto en la memoria. Los datos básicos buscarán de manera eficiente lo que desee solo cuando lo necesite.

+0

"Java mucho más lento". cualquier punto de referencia? –

+0

NSArray no es particularmente rápido, por lo que, aunque puede no ser la única causa del problema de rendimiento, no servirá de nada. –

+0

Nunca he visto que Java sea el mejor lenguaje compilado en el mismo hardware. Como notó NSD, la mensajería de Objective-C lo hace más lento que simplemente C (que es parte de por qué no puedes usarlo para los controladores) pero es mucho más rápido que una VM por mucho. Creo que el OP está comparando inconscientemente el rendimiento de Java en un sistema no incorporado con el rendimiento de Objective-C en el iPhone incorporado y asumiendo que el problema es con el idioma/API en lugar del hardware. Si no tiene una idea de la velocidad del hardware, perderá tiempo buscando cuellos de botella que no existen. – TechZen

4

Si ve problemas de rendimiento, mida dónde está gastando su tiempo, no adivine. Apple proporciona un excelente conjunto de herramientas de medición del rendimiento.

+1

Si bien el loro de Knut suele ser seguro e impresionante para los demás, no hay que adivinar si se trata de meter miles de objetos en una matriz administrada en un sistema incrustado de recursos. –

+3

Estoy seguro de que piensas que fue una ingeniosa traslucción de tu parte, pero estás equivocado. Tengo una gran experiencia de primera mano con personas nuevas en Objective-C que hacen conjeturas sobre dónde estaban sus problemas de rendimiento. Pasé tres años y medio en Apple, incluyendo más de un año como el único ingeniero de Cocoa en DTS. – NSResponder

+0

@NSResponder No soy nuevo en Obj-C y no tengo ningún problema de rendimiento. Lo probé con instrumentos y no es una suposición ... El problema es con la administración de unos cientos de miles de objetos y mostrarlos. Tengo una base de datos SQLite que ayuda a almacenar y recuperar todo fácilmente, pero la pregunta es: ¿cómo mostraría toda esa masa de datos dentro de una UITableView. Así que una opción sería siempre recuperar cosas de mi SQLite db cada vez que quiero mostrar algo. La otra opción en la que pensé fue usar un objeto de memoria circular. NSD tiene razón, y su respuesta es offtopic. – natanavra

0

Puede usar las clases de STL en "Objective-C++", que es un nombre elegante para Objective-C haciendo uso de las clases de C++. Simplemente nombra los archivos fuente que usan el código C++ con una extensión ".mm" y obtendrás el tiempo de ejecución mixto.