【问题标题】:How do I Increase the speed of this sqlite db query / object creation in Objective-C?如何在 Objective-C 中提高这个 sqlite db 查询/对象创建的速度?
【发布时间】:2010-02-14 03:03:34
【问题描述】:

我有以下方法在 iPhone 上查询 sqlite 数据库表 它从表中提取大约 6,000 行,然后根据这些信息循环创建 6,000 个对象并将它们填充到一个数组中。

while 循环有点慢(在我的设备上遍历它们大约需要 10 秒) 有什么想法可以加快速度吗?

TKS!!!

NSMutableArray  *dees              = [[NSMutableArray alloc] init];

if(sqlite3_open([database_path UTF8String], &database) == SQLITE_OK) {
  const char      *sqlStatement = "select cn, gn, df, or, id from doits order by lower(cn)";
  sqlite3_stmt    *compiledStatement;
  if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {

    //loop through the results and feed them into the array
    while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
        // Read the data from the result row
        NSString    *a_cn             = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
        NSString    *a_gn             = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
        NSString    *a_df             = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
        NSString    *an_or            = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
        NSString    *ident            = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 4)];

        DL   *dl = [[DL alloc] init];
        dl.cn            = a_cn;
        dl.gn            = a_gn;
        dl.df            = a_df;
        dl.or            = an_or;
        dl.primary_id    = [ident intValue];
        [dees      addObject:dl];
    }
}
sqlite3_finalize(compiledStatement);

【问题讨论】:

    标签: iphone sqlite nsmutablearray while-loop


    【解决方案1】:

    为什么要在运行时创建所有 6K?延迟加载它们并仅在需要时创建所需的项目怎么样?

    iphone 不是台式电脑,它的 CPU 频率为 400+MHz,迭代 6K 结果会很慢。

    您的表是否正确编入索引?您能否优化架构(字段类型?)?除了迭代 6K 元素之外,您实际上并没有做太多事情 - 所以我看不到优化该循环的直接方法。

    我会看大图并尝试找到一种方法来延迟加载或部分加载数据。假设您使用数据填充 UITableView,也许您只需要第一层,而不是完全成熟的对象?

    编辑:

    我所说的字段类型是指您的数据库中有 4 个“sqlite3_column_text”文本字段。您是否必须使用文本字段,或者您是否可以使用更小且可能更适合您的数据的内容?

    【讨论】:

    • 是的,我正在使用 6,000 行来填充 UITableView。表格视图可以通过用户在搜索框中键入来“实时”过滤......并且在我的查询中检索到的所有字段都在实时搜索中进行搜索。所以,除非我在考虑这个错误(很可能),否则我认为我从一开始就需要所有 6,000 行。我不确定您所说的“第一层”是什么意思,而不是完全成熟的对象。你是在建议我把所有东西都塞进一个 NSArray 的 NSArray 中吗? TKS
    • 另外,不太清楚关于架构优化的“字段类型”是什么意思。
    • 没有办法让所有 6,000 个元素的加载速度更快。因此,您必须找到一种方法来避免一次性加载所有 6,000 个元素。您可以使您的容器类比 NSArray 更智能,而不是加载所有 6k 元素,只加载其中一些元素。当您的搜索进入时,您的容器类可以确定它是否可以满足来自内存中项目的请求,或者它是否需要从数据库加载更多内容(惰性搜索)。或者,您需要加载表格的每一列,还是只加载元素的一部分并根据需要检索其余部分?
    • 谢谢,但我需要加载所有描述的列(用户可以搜索查询中选择的任何列)。 TYVM
    【解决方案2】:

    正如 Mr-sk 所说,出于内存和性能原因,一次加载所有 6,000 个元素是个坏主意。您需要批量获取,以便在任何给定时间仅在屏幕上加载元素。对于运行搜索,您需要对数据库执行这些查询。

    如果您要将数据模型切换为使用 Core Data,那么在 NSFetchRequest 上使用 NSFetchedResultsController 和 -setFetchBatchSize: 将变得微不足道。仅将您需要的数据提供给表格视图正是这个类的目的。对于搜索,您可以提供一个基于搜索条件过滤结果的 NSFetchRequest。这将大大提高您的应用程序的性能。

    【讨论】:

      【解决方案3】:

      将结果对象添加到数组后,能不能释放一下,看看性能有没有提升。

      [dees addObject:dl];

      [d1 版本];

      您正在做的是动态创建 hte 对象并将其添加到数组中,但是一旦添加,您实际上并没有释放对象。我猜这是内存泄漏。

      谢谢

      苏雷什·库马尔·纳拉亚纳萨米

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-27
        • 2017-01-28
        • 1970-01-01
        • 2019-10-09
        相关资源
        最近更新 更多