2010-09-29 2 views
0

Я создаю приложение iphone/ipad, которое в основном читает документы XML и создает табличные представления из объектов, созданных на основе xml. Xml представляет собой «уровень» в файловой системе. Это в основном браузер.Основные данные - получить/создать производительность NSManagedObject

Каждый раз, когда я разбираю документы xml, я обновляю файловую систему, которая зеркалируется в базе данных sqlite core-data. Для каждого «файла», встречающегося в xml, я пытаюсь связать связанный с ним NSManagedObject.

Проблема в этой функции, которую я использую для создания/создания либо нового пустого объекта, либо получения существующего из базы данных.

+(File*)getOrCreateFile:(NSString*)remotePath 
     context:(NSManagedObjectContext*)context 
{ 
     struct timeval start,end,res; 
     gettimeofday(&start,NULL); 
     NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
     NSEntityDescription *entity = [NSEntityDescription entityForName:@"File" inManagedObjectContext:context]; 
     [fetchRequest setEntity:entity]; 
     [fetchRequest setFetchLimit:1]; 
     NSPredicate *predicate = [NSPredicate predicateWithFormat:@"remotePath == %@",remotePath]; 
     [fetchRequest setPredicate:predicate]; 

     NSError *error; 
     NSArray *items = [context executeFetchRequest:fetchRequest error:&error]; 
     [fetchRequest release]; 

     File *f; 
     if ([items count] == 0) 
      f = (File*)[NSEntityDescription insertNewObjectForEntityForName:@"File" inManagedObjectContext:context]; 
     else 
      f = (File*)[items objectAtIndex:0]; 

     gettimeofday(&end, NULL); 
     [JFS timeval_subtract:&res x:&end y:&start]; 
     count++; 
     elapsed += res.tv_usec; 
     return f; 

}

Для eksample, если я разбора документа с 200ish файлов общее время на iPhone 3G составляет около 4 секунд. 3 из этих секунд расходуются на эту функцию, получая объекты из основных данных.

RemotePath - это уникальная строка переменной длины и индексируется в базе данных sqllite.

Что я здесь делаю неправильно? или .. что я мог бы сделать лучше/отличным для улучшения производительности.

ответ

0

Выполнение изъятий несколько дороже в Core Data, хотя инженеры Core Data сделали некоторые удивительные работы, чтобы этот хит был минимальным. Таким образом, вы можете немного улучшить ситуацию, выполнив выборку для возврата сразу нескольких элементов. Например, партия в remotePaths и выборка с предикатом, такими как

[NSPredicate predicateWithFormat:@"remotePath IN %@", paths]; 

, где дорожка представляет собой набор возможных путей.

Из результатов вы можете выполнить поиск в памяти, чтобы определить, присутствует ли конкретный путь.

Принципиально, однако, выполнение выборок против строк (даже при индексировании) является дорогостоящей операцией. Возможно, вы не сможете многое сделать. Рассмотрите выборку атрибутов, отличных от строки, возможно, путем добавления пути и сохранения хеша в объекте. Вы вернете (потенциально) больший результирующий набор, который вы могли бы искать в памяти для равенства строк.

И, наконец, не делайте любых изменений без каких-либо данных о производительности. Профиль, профиль, профиль.

+1

В datamodel каждая папка имеет отношение к каждому ребенку (папка/файл). Я закончил использование [NSFetchRequest setRelationshipKeyPathsForPrefetching: [NSArray arrayWithObject: @ "children"], и это возвратило каждый ребенок как ошибку, а затем каждый раз вместо вызова другой функции я искал теперь в наборе памяти детей с использованием NSPredicate. Через 4 секунды от исходного сообщения теперь 1.5ish. –

Смежные вопросы