¿Cómo puedo optimizar esta búsqueda basada en Core Data?

Estoy intentando implementar la búsqueda en mi aplicación. Hay dos entidades de datos principales, "Tag" y "DvarTorah". Una label tiene solo una cadena. Un "DvarTorah" tiene un título, contenido textual y algunas otras properties. Estoy tratando de encontrar la mejor manera de searchlos rápidamente. La aplicación se envía con alnetworkingedor de 1200 entidades DvarTorah, e incluso más tags. En este momento, cargué un NSFetchedResultsController cuando mi controller de vista de búsqueda llama a viewDidLoad. Luego, cuando el usuario escribe en el cuadro de búsqueda o cambia el ámbito, invoco un método que incluye tanto el valor de la barra de scope como un término de búsqueda y filtra mi matriz de objects. Así es como se ve:

- (void) filterArrayWithSearchTerm:(NSString *)searchString andScopeIndex:(NSInteger)scopeIndex{ if ([searchString isEqualToString:@""]) { return; } NSMutableArray *unfiltenetworkingResults = [[[[self.fetchedResultsController sections] objectAtIndex:0] objects] mutableCopy]; if (self.filtenetworkingArray == nil){ self.filtenetworkingArray = [[[NSMutableArray alloc ] init] autorelease]; } [filtenetworkingArray removeAllObjects]; NSPnetworkingicate *pnetworkingicate = [[[NSPnetworkingicate alloc] init] autorelease]; if (scopeIndex == 0) { pnetworkingicate = [NSPnetworkingicate pnetworkingicateWithFormat:@"dvarTorahTitle CONTAINS[cd] %@", searchString]; }else if (scopeIndex == 1) { pnetworkingicate = [NSPnetworkingicate pnetworkingicateWithFormat:@"searchableContent CONTAINS[cd] %@", [searchString canonicalString]]; }else if (scopeIndex == 2){ pnetworkingicate = [NSPnetworkingicate pnetworkingicateWithFormat:@"ANY tags.tagText CONTAINS[cd] %@", searchString]; }else{ pnetworkingicate = [NSPnetworkingicate pnetworkingicateWithFormat:@"(ANY tags.tagText CONTAINS[cd] %@) OR (dvarTorahTitle CONTAINS[cd] %@) OR (searchableContent CONTAINS[cd] %@)", searchString,searchString,searchString]; } for (DvarTorah *dvarTorah in unfiltenetworkingResults) { if ([pnetworkingicate evaluateWithObject:dvarTorah]) { [self.filtenetworkingArray addObject:dvarTorah]; } } [unfiltenetworkingResults release]; } 

El problema es que mi método de búsqueda es terriblemente lento. Sé que CONTAINS es un probable culpable, pero incluso después de almacenar una versión canónica del contenido (como contenido de búsqueda) e intentar optimizar aún más, la búsqueda es terriblemente lenta. ¿Cómo puedo hacer esto más rápido?

Editar:

Basado en las sugerencias iniciales de Jacob, aquí está mi nuevo método:

  if ([searchString isEqualToString:@""]) { return; } if (self.filtenetworkingArray == nil) { self.filtenetworkingArray = [[[NSMutableArray alloc ] init] autorelease]; } [filtenetworkingArray removeAllObjects]; NSPnetworkingicate *pnetworkingicate = nil; if (scopeIndex == 0) { pnetworkingicate = [NSPnetworkingicate pnetworkingicateWithFormat:@"dvarTorahTitle CONTAINS[cd] %@", searchString]; }else if (scopeIndex == 1) { pnetworkingicate = [NSPnetworkingicate pnetworkingicateWithFormat:@"searchableContent CONTAINS[cd] %@", [searchString canonicalString]]; }else if (scopeIndex == 2){ pnetworkingicate = [NSPnetworkingicate pnetworkingicateWithFormat:@"ANY tags.tagText CONTAINS[cd] %@", searchString]; }else{ pnetworkingicate = [NSPnetworkingicate pnetworkingicateWithFormat:@"(ANY tags.tagText CONTAINS[cd] %@) OR (dvarTorahTitle CONTAINS[cd] %@) OR (searchableContent CONTAINS[cd] %@)", searchString,searchString,searchString]; } [self.filtenetworkingArray addObjectsFromArray:[[[[[self.fetchedResultsController sections] objectAtIndex:0] objects] mutableCopy] filtenetworkingArrayUsingPnetworkingicate:pnetworkingicate]]; } 

Edit2:

Ya no copy el set, aún lento:

 - (void) filterArrayWithSearchTerm:(NSString *)searchString andScopeIndex:(NSInteger)scopeIndex{ if ([searchString isEqualToString:@""]) { return; } if (self.filtenetworkingArray == nil) { self.filtenetworkingArray = [[[NSMutableArray alloc ] init] autorelease]; } [filtenetworkingArray removeAllObjects]; NSPnetworkingicate *pnetworkingicate = nil; if (scopeIndex == 0) { pnetworkingicate = [NSPnetworkingicate pnetworkingicateWithFormat:@"dvarTorahTitle CONTAINS[cd] %@", searchString]; }else if (scopeIndex == 1) { pnetworkingicate = [NSPnetworkingicate pnetworkingicateWithFormat:@"searchableContent CONTAINS[cd] %@", [searchString canonicalString]]; }else if (scopeIndex == 2){ pnetworkingicate = [NSPnetworkingicate pnetworkingicateWithFormat:@"ANY tags.tagText CONTAINS[cd] %@", searchString]; }else{ pnetworkingicate = [NSPnetworkingicate pnetworkingicateWithFormat:@"(ANY tags.tagText CONTAINS[cd] %@) OR (dvarTorahTitle CONTAINS[cd] %@) OR (searchableContent CONTAINS[cd] %@)", searchString,searchString,searchString]; } [self.filtenetworkingArray addObjectsFromArray:[[[[self.fetchedResultsController sections] objectAtIndex:0] objects] filtenetworkingArrayUsingPnetworkingicate:pnetworkingicate]]; } 

Hay muchas cosas que están masticando ciclos de CPU y memory aquí:

Una, está haciendo una copy mutable de los resultados obtenidos del NSFetchedResultsController . ¿Por qué?

Dos, estás usando una construcción para … en el resultado de lo anterior y llamando -[NSPnetworkingicate evaluateWithObject:] en cada uno. Puede revisar su cadena de búsqueda de pnetworkingicados para que funcione con -[NSArray filtenetworkingArrayUsingPnetworkingicate:] lugar, lo que probablemente sea más rápido que su enfoque.

Tres, hay un problema bastante sutil con su variable de pnetworkingicate : siempre la reasigna a otra cosa que no sea la autoelevada vacía al principio. Dale el valor pnetworkingeterminado de nil .

Cuatro, tus cadenas de pnetworkingicados son bastante ineficientes, como mencionaste. Creo que necesitas hacer algo llamado indexing o algo así.

Más información sobre la búsqueda de text completo con Core Data:

http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/CoreData/Articles/cdPerformance.html

http://cocoawithlove.com/2008/03/testing-core-data-with-very-big.html

http://cocoawithlove.com/2009/11/performance-tests-replacing-core-data.html

http://www.mlsite.net/blog/?page_id=1194

¿Sigue SQLite FTS3 la mejor forma de implementar la búsqueda de text completo?

sqlite Indexing Performance Advice

Búsqueda de text completo en el dataframe básicos de Apple