使用一对多关系的CoreData性能

时间:2013-11-04 21:24:42

标签: performance core-data

我有一个iPad应用程序,如果它在屏幕上,它会连续记录手指位置(每秒最多30次),并为记录的每个数据集保存“样本”对象到核心数据。过了一会儿,也许两三分钟,这个过程或者至少用户的反馈变得非常慢。如果我关闭应用程序并重新启动它从一开始就很慢,但删除持久存储有助于使其恢复到原始性能。因此,我认为问题应该与数据存储有关。

我试图用时间分析器检测问题,但大部分时间都是由系统库和非Objective-C代码消耗的。如果我将其关闭以进行分析,那么最耗时的方法是初始化样本对象:

@implementation Sample (Create)
+(Sample *)sampleWithTime:(double)time
             xValue:(double)x
             yValue:(double)y
          eventType:(EventType)event
        chillStatus:(BOOL)chill 
        participant:(Participant *)whoListened
              track:(Track *)whichTrack
inManagedObjectContext:(NSManagedObjectContext *)context
{
   Sample *sample; 
   if (!sample) {
    sample = [NSEntityDescription insertNewObjectForEntityForName:@"Sample" inManagedObjectContext:context];
     sample.time = time;
     sample.x = x;
     sample.y = y;
     sample.event = event;
     sample.chillStatus = chill;
     sample.whichTrack = whichTrack;
     sample.whoListened = whoListened;
   }
   return sample;
}

sample.whichTrack =哪条曲目;设置与给定方法的track-object(ManagedObject子类,指的是正在播放的音乐)的关系。它是一对多的关系,因为每个样本只有一个轨道,但每个轨道有很多样本。这条线占用了整个方法的87%的时间,即使下一行完全正确同样的,与此相比几乎不需要任何东西。

这在这里搜索问题是否有意义?数据库可以变得那么慢,因为关系中的对象集变得更大,必须被复制才能添加对象或类似的东西吗?我能做些什么来提高性能吗?作为文件的数据库根本不会变大,它仍然不到1 MB。

1 个答案:

答案 0 :(得分:1)

在那里搜索问题很有意义。

我假设您在whichTrack对象上设置samples(to-one)关系与反Track(对多)关系。

你需要30 Sample s / sec ==>同一Track上的3分钟采样将保持:多对多关系中的5400个对象。这种关系在两端保持不变,这意味着无论何时插入新样本,都必须从商店中获取整个对象集(至少是它们的错误)(如果还没有出现故障)。
如果您在每个新Sample之后保存并释放上下文(重置或刷新Track对象),则下次访问{时,将需要重新获取多对多关系中的所有现有项目{1}}项目。

我会先尝试删除反向关系(Track实体的多对侧)并查看其行为。
请注意,这将消除Track删除(Track个对象)后的任何级联。

如果您仍然需要在Sample删除后进行级联,则可以通过向Track实体添加prepareForDeletion实施方案来自行添加。

另一个解决方案(更优雅)是将您的样本分成Track个对象 SampleContainer对象与Track之间存在多对多的关系 每个容器将限于'N'个样本 填充容器后,将新容器添加到SampleContainer

除此之外:
您可以仅在每个'T'时间间隔执行保存。这将进一步减少商店访问(保存),但这可能不适合您,因为如果用户在两次保存之间终止应用程序(您可以在转到后台之前总是保存),您可能会松开Track