我有一个文字游戏应用程序,可以访问单词和线索列表,大约有 10 万个条目。数据库只被访问,从不改变。我使用 SQL 方法构建了应用程序,它在 iOS 6 上运行良好,但在 iOS 5 上从数据库中获取新线索的时间非常慢:
- iOS 5 使用 SQL 从 100K 中获取一条记录大约需要 12 秒。
- iOS 6 使用 SQL 从 100K 中获取一条记录大约需要 700-1000 毫秒。
这两个都在 32 GB iPod Touch 上。
鉴于这种性能,我使用 Core Data 制作了一个版本。我的方法通过首先计算适合查询的记录,然后随机选择一个来获得随机数据库条目。代码如下。我读到的所有内容都表明 Core Data 会更快:
- iOS 5,计数记录大约需要 4 秒,检索其中一条记录大约需要 50 - 1500 毫秒。总时间约5秒。
- iOS 6,计数记录需要 2 秒多一点,检索其中一条记录大约需要 300-500 毫秒。总共约3秒。
因此,与 SQL 相比,Core Data 在 iOS 5 上更快,但在 iOS 6 上更慢。就我而言,无论哪种方式,性能都太慢了。我知道开销来自下面给出的方法(对于核心数据版本)。所以,两个问题:
- 关于这个问题的任何一般性建议,着眼于理解它并提高性能?
- 具体来说,下面附加的核心数据代码怎么样:我做了什么愚蠢的事情来减慢它的速度吗?还是我应该添加其他东西来加快速度?这是我对 Core Data 的第一次尝试。
谢谢。
- (NSArray *) randomClue {
NSManagedObjectContext* context = [self managedObjectContext];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"A"];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"WL28"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [self createSearchQuery];
[fetchRequest setPredicate:predicate];
NSError *error;
NSDate *date1 = [NSDate date];
NSString *timeString1 = [formatter stringFromDate:date1];
int resCount = [context countForFetchRequest:fetchRequest
error:&error];
NSDate *date2 = [NSDate date];
NSString *timeString2 = [formatter stringFromDate:date2];
int t1 = [timeString1 intValue];
int t2 = [timeString2 intValue];
int d1 = t2-t1;
NSLog(@"randomClue:");
NSLog(@" Time to count array entries: %i", d1);
int ranNum = arc4random_uniform(resCount-1);
int ranNum2 = ranNum + 1;
// Now we fetch just one answer object, not a whole database or even a piece of it!
[fetchRequest setReturnsObjectsAsFaults:YES];
[fetchRequest setPropertiesToFetch:nil];
[fetchRequest setFetchLimit:1];
[fetchRequest setFetchOffset:ranNum2];
NSDate *date3 = [NSDate date];
NSString *timeString3 = [formatter stringFromDate:date3];
self.wl28 = [context executeFetchRequest:fetchRequest error:&error];
NSDate *date4 = [NSDate date];
NSString *timeString4 = [formatter stringFromDate:date4];
int t3 = [timeString3 intValue];
int t4 = [timeString4 intValue];
int d2 = t4-t3;
NSLog(@" Time to retrieve one entry: %i", d2);
return self.wl28;
}
编辑:在下面添加了 createSearchQuery
- (NSPredicate *)createSearchQuery {
NSMutableArray *pD = [[GameData gameData].curData valueForKey:@"persData"];
NSNumber *currMin = [pD objectAtIndex:0];
NSNumber *currMax = [pD objectAtIndex:1];
NSNumber *dicNo = [pD objectAtIndex:2];
NSString *dict = nil;
if ([dicNo intValue] == 0) dict = @"TWL";
if ([dicNo intValue] == 1) dict = @"LWL";
NSPredicate *dictPred = [NSPredicate predicateWithFormat:@"dict == %@", dict];
NSPredicate *lowNoCPred = [NSPredicate predicateWithFormat:@"noC >= %@", currMin];
NSPredicate *highNoCPred = [NSPredicate predicateWithFormat:@"noC <= %@", currMax];
NSPredicate *query = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray
arrayWithObjects:dictPred, lowNoCPred, highNoCPred,nil]];
NSLog(@"%@", query);
return query;
}