2010-08-24 16 views
5

Estoy tratando de importar una gran cantidad de datos en un almacén de datos central en el iPhone. Estoy usando un respaldo SQLite para el almacén de datos central. Parece que lleva más tiempo de lo que esperaría. Recorté las rutinas para que, básicamente, solo intente buscar un objeto (para ver si ya existe) y luego crear un nuevo objeto si no lo hace (nunca lo hacen porque estoy importando datos). Sin embargo, la búsqueda no es la parte que consume mucho tiempo. Es la creación de los objetos. Básicamente, el código erróneo es:¿Cómo puedo mejorar el rendimiento de la inserción de objetos de Core Data en iPhone?

MobileObject *newObject = (MobileObject *)[NSEntityDescription insertNewObjectForEntityForName:objDesc inManagedObjectContext:managedObjectContext]; 

me he dado cuenta de que en el simulador, es bastante rápido en el inicio con cerca de 100 objetos creados un segundo. Sin embargo, se ralentiza y para cuando se crean cinco mil objetos, son casi 2 segundos para 100 objetos y para cuando se crean diez mil objetos, son 4 segundos por cada 100 objetos. El grupo completo de 21000 objetos toma más de 10 minutos. Eso es con todo el código realmente útil eliminado (eso es solo una búsqueda y un objeto creado). Y es mucho más lento en el dispositivo real (tal vez 4 veces más).

Lo que no entiendo es por qué los datos del núcleo comienzan rápidamente pero luego comienzan a desacelerarse. He intentado tanto con índice como sin índices en mis datos. Intenté crear mi propio grupo de autorrelease, que periódicamente agoto en mi ciclo. Intenté guardar después de cada creación de objeto. Intenté esperar hasta el final para guardar. Pero no importa lo que haga, el rendimiento aún parece miserable. ¿Es tan lento agregar un nuevo objeto a un almacén de datos central con algunos miles de objetos en él? ¿Alguna sugerencia?

+0

Debo comentar que en realidad creo que las capturas son las que ocupan una cantidad significativa de tiempo. Supongo que tiene sentido ya que a medida que la tienda se hace más grande, hay más objetos para buscar. – Mike

+0

Como un lado, el molde en su código de ejemplo anterior es innecesario. '-insertNewObjectForEntity ...' devuelve un 'id' y, por lo tanto, no se debe ni se debe convertir. –

+1

Crear una gran base de datos de esta manera puede ser increíblemente lento si espera hasta el final para guardar. Generalmente guardo después de cada pocos miles de objetos nuevos, no he experimentado para encontrar la frecuencia óptima. –

Respuesta

0

Pruebe usar Instruments. ¿No guardas después de insertar cada objeto? En realidad, más códigos y esquemas relacionados con las inserciones pueden ser muy útiles.

2

Puede ser bastante rápido, pero depende de lo que esté haciendo. Como otros han sugerido que debería mirar Instrumentos y encontrar el punto de acceso real. También publicar el código de importación real ayudaría a identificar el problema.

+0

Para mí, * estoy * usando Instruments y me dice _sharedIMPL_addObjectToSet_core toma el 99% de el tiempo - a su vez, el observador de valores clave de NSObject toma el 50%, y _PF_ManagedObject_DidChangeValueForKeywithSetMutation toma el otro 50%.Estoy conectando una relación de muchos a muchos entre miles de entidades de "Sentencia"; estas son traducciones entre sí. Incluso después de probar algunas optimizaciones, el culpable lento es realmente la relación "inserción" que probablemente se produce entre bastidores en CoreData. Me da la sensación de que esto sería al menos un 50% más rápido si se usa sqlite directo :-P – Jonny

+0

SQLite es más rápido que Core Data. Core Data no va a ser el más rápido, es el más sostenible. En cuanto a los instrumentos, oculte las bibliotecas del sistema, alise la recursión e invierta el árbol de llamadas. Luego vea qué hay encima que es ** SU código **. Eso es lo que necesitas arreglar. Cuando encuentre el método que le pertenece, haga doble clic en él e Instrumentos le mostrará qué es * lento * dentro * de ese método. –

+0

Eso es exactamente lo que hice. Rebusqué en mi función que contenía un bucle de un par de cientos de miles de relaciones de muchos a muchos para una sola entidad: sí, esas oraciones son traducciones entre sí. Estaba pensando que los NSDictionaries intermedios que utilicé para los datos de origen fueron lentos con la indexación e hice algunas optimizaciones allí, pero los Instrumentos claramente demostraron que el problema no es sobre NSDictionary, solo las operaciones de inserción internas. Que realmente usa sqlite al final. La última vez que probé Core Data, también tuve problemas con un rendimiento demasiado lento y fui solo con Sqlite. – Jonny

0

Estoy teniendo este problema también. Importación de 100.000 objetos simples desde un almacén de datos remoto, y he seguido las notas de Apple sobre la importación en lotes. Los primeros pocos lotes (de 2.000 objetos cada uno) comienzan razonablemente, y luego los guarda se ralentizan a paso de tortuga.

He dividido los datos aún más en lotes de 50, y todavía era lento. Los instrumentos muestran que los ahorros se toman cada vez más y más. No estoy seguro de por qué, estoy creando un nuevo contexto para cada lote, y el administrador de deshacer está configurado como nulo.

Lamentablemente, no tengo nada útil para agregar a esta conversación ... todavía. Se actualizará más tarde.

+0

El siguiente paso sería aislar el problema en un proyecto de prueba para que otros puedan verlo y, potencialmente, si no se puede resolver, envíelo a Apple como un radar. Al igual que con el OP, una línea de código o una descripción no permite que nadie más lo ayude. –

Cuestiones relacionadas