【问题标题】:Huge size core-data object巨大的核心数据对象
【发布时间】:2012-03-26 14:34:55
【问题描述】:

我试图将 20 万条消息添加到核心数据对象中,以证明 Twitter 应用程序的概念。这很好用,我的实体也被添加了。我有一个UISearchBar 和一个UITableView 来显示这些。然而,对于每一个新的 1000 个对象,我的时间似乎呈指数增长。这是正常的吗?我希望CoreData 能够很好地处理大型数据集。您对处理如此庞大的数据集有更好的建议吗?我想知道Dictionary apps 是如何工作的。

我的控制台输出在这里:

-2012-03-26 22:19:28.126 TweetReader[3668:707] 完成 1000
-2012-03-26 22:19:40.335 TweetReader[3668:707] 2000 年完成
-2012-03-26 22:19:55.136 TweetReader[3668:707] 完成 3000
-2012-03-26 22:20:18.569 TweetReader[3668:707] 完成 4000
-2012-03-26 22:20:50.166 TweetReader[3668:707] 完成 5000
-2012-03-26 22:21:30.284 TweetReader[3668:707] 完成 6000
-2012-03-26 22:22:19.096 TweetReader[3668:707] 完成 7000
-2012-03-26 22:23:16.091 TweetReader[3668:707] 完成 8000
-2012-03-26 22:24:21.321 TweetReader[3668:707] 完成 9000
-2012-03-26 22:25:35.017 TweetReader[3668:707] 完成 10000
-2012-03-26 22:26:57.250 TweetReader[3668:707] 完成 11000
-2012-03-26 22:28:27.563 TweetReader[3668:707] 完成 12000
-2012-03-26 22:30:06.202 TweetReader[3668:707] 完成 13000
-2012-03-26 22:31:52.645 TweetReader[3668:707] 完成 14000

这是我保存到CoreData的代码:

for (NSInteger i = 1; i <= 200000; i++) {

NSAutoreleasePool * myPool = [[NSAutoreleasePool alloc] init];

Tweet *tweetie = [NSEntityDescription insertNewObjectForEntityForName:@"Tweet" inManagedObjectContext:self.managedObjectContext];
    tweetie.name = [NSString stringWithFormat:@"%10d",i];
    tweetie.message =[NSString stringWithFormat:@"%10d",i];
    // Save the context after 1000 objects.
    if (! (i % 1000)) {
        NSError *error;
        NSLog(@"Done %d",i); 
        if (![managedObjectContext save:&error]) {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }

        [myPool release];
    }
}

【问题讨论】:

  • 您是在抱怨添加速度慢,还是在添加完成后使用数据集?
  • 另外,您正在为循环的每次迭代创建一个新的自动释放池 - 这是一个坏主意。
  • 添加速度慢。在实际的 iPhone 3gs 上添加 200k 个对象花了将近​​ 2 个小时。
  • 添加后,UISearchBar 和抓取工作正常,虽然不如我见过的字典应用程序好。感谢您指向自动释放池,我将更改此设置,看看是否有任何时间改进。

标签: objective-c ios core-data dataset nsmanagedobject


【解决方案1】:

嘿,如果您有 200k 条消息,请首先找到适合每条消息长度的最佳存储方式。这将是反复试验,我发现 3000 是最佳的。每 3000 次执行 [保存上下文] 例如:

      for(i=0; i<num of objects;i++)
      { // form the object to be saved in context

      if(i%3000==0){ // save the num of records , optimum value
        NSError *error;
        NSLog(@"saved rec nu %d",i);
        if (![context save:&error]) {
            NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
            return NO;
       }

        [context processPendingChanges];// most important thing , if not objects will 
              // keep adding in context and time would for insertion would drastically increase.
     }
        //for last set of the objects which are less than 3000
        NSError *error;
        NSLog(@"saved rec nu %d",i);
        if (![context save:&error]) {
            NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
            return NO;



    }

如果有什么,请告诉我..

【讨论】:

    【解决方案2】:

    您在数据库中为哪些列编制了索引?您是否尝试在添加时锁定上下文以查看它是否可以优化这一点(即以事务方式进行插入?)

    Core Data 在批量插入方面是出了名的糟糕。解决这个问题的方法可能是直接使用 sqlite - 请参阅这篇文章,了解必须这样做的人的真实案例研究:http://inessential.com/2010/02/26/on_switching_away_from_core_data

    【讨论】:

    • 确实是一篇非常好的文章。我到处读到很多关于 sqlite 核心数据的赞美。这让我大开眼界。
    • 我没有索引(一个普通的核心数据实体,带有名称和消息)。我会尝试锁定上下文(虽然我不知道该怎么做)。
    • 谢谢院长。与 Sqlite 相同的事情只需要几秒钟。当核心数据不是正确答案时,此代码可能可以作为示例。我仍然会尝试尽可能多地使用核心数据来优化它,然后发布与 sqlite 的更好的时序比较。
    猜你喜欢
    • 2015-07-20
    • 1970-01-01
    • 2012-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多