0

我有一个文字游戏应用程序,可以访问单词和线索列表,大约有 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 上更慢。就我而言,无论哪种方式,性能都太慢了。我知道开销来自下面给出的方法(对于核心数据版本)。所以,两个问题:

  1. 关于这个问题的任何一般性建议,着眼于理解它并提高性能?
  2. 具体来说,下面附加的核心数据代码怎么样:我做了什么愚蠢的事情来减慢它的速度吗?还是我应该添加其他东西来加快速度?这是我对 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;
}
4

1 回答 1

0

您可以尝试将索引添加到实体内的 noC 和/或 dict 属性。它可能会加快您的查询时间。

于 2012-10-27T18:42:21.770 回答