iOS实现理论

我们(IT部门在工作)正在build立一个iPad应用程序,它将采用数字标识并在表格中提供一个简单的查找。 它本质上是在一个表上进行主键search,并在小处理后显示一个字段。

警告

该表中有450万行,需要最多1秒的查找时间。 它不会有互联网连接,所以它必须发生在设备上。 我们有一些想法,但最有意义的是:

  1. Sqlite:它会站起来这样的虐待? 它可以处理多行,它会做得好吗?

  2. 平面文件search:我们可以自己循环播放文件,也可以将它们分成前几位,做一些更智能的索引。

  3. 卸载到可以通过API处理的设备上的某个第三方数据库应用程序。

  4. 完全是我们无尽的智慧,我们已经错过了。

我必须借此机会感谢苹果让这个testing非常容易。 如果没有Mac或Dev许可证,我们不希望超过2000英镑,直到我们知道我们可以把它完成。

SQLite是惊人的快速。 有450万条logging的testing表具有这样的结构:

CREATE TABLE testtable (numericid INTEGER PRIMARY KEY, testtext TEXT); 

它填充了numericid(0,1,…)和testText的一个string的递增值。

在MacBook Pro(2009)上以primefaces方式完成所有插入需要1小时42分钟。 生成的SQLite文件大小为94 MB。

在iOS应用程序中,数据库在viewDidLoad方法中打开。 一个简单的button触发数据库查询是这样的

 - (void)btnPressed:(UIButton *)sender{ NSLog(@"btn pressed, start"); sqlite3_stmt *statement = nil; NSString *querystring; querystring= [NSString stringWithFormat:@"SELECT * FROM testtable WHERE numericid = 2571312;"]; const char *sql = [querystring UTF8String]; NSLog(@"sql is: %s", sql); if (sqlite3_prepare_v2(dbConnection, sql, -1, &statement, NULL)!=SQLITE_OK){ NSLog(@"sql problem occured with: %s", sql); NSLog(@"%s", sqlite3_errmsg(dbConnection)); } else { while (sqlite3_step(statement) == SQLITE_ROW) { NSString *numericid = [NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 1)]; NSString *testtext = [NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 0)]; NSLog(@"%@",[NSString stringWithFormat:@"%@ (%@)", numericid, testtext]); } // while } sqlite3_finalize(statement); NSLog(@"btn pressed, finished"); } 

结果输出:

 2012-08-10 17:51:36.734 DBQueryTest[28462:707] Database Successfully Opened 2012-08-10 17:51:39.083 DBQueryTest[28462:707] btn pressed, start 2012-08-10 17:51:39.087 DBQueryTest[28462:707] sql is: SELECT * FROM testtable WHERE numericid = 2571312; 2012-08-10 17:51:39.099 DBQueryTest[28462:707] text2571312 (2571312) 2012-08-10 17:51:39.102 DBQueryTest[28462:707] btn pressed, finished 

所以一个查询需要19ms以下 ! 虽然我没有为统计评估运行一个完全随机的testing,但是可以复制几个numericid值。

结论:该testing设置满足您的要求。 SQLite绝对是一种方式。

更新:

具有100000个键值的快速随机访问testingvalidation了第一个结果。 离开sql语句string的创build和耗时的NSLog输出的时间测量,平均数据库查询时间下降一个数量级:

平均查询时间 :1.8毫秒

平均偏差 :0.4毫秒

最大查询时间 :25.9毫秒

最小查询时间 :0.6 ms

虽然Sqlite应该可以正常工作,但这可能是矫枉过正的。 一个简单的二进制search应该是你所需要的。 如果一个大文件的速度太慢,可以用前两位数字分割成10或100个子文件。

或者,您可以将数据加载到支持二进制search的CFArrayBSearchValues (请参阅CFArrayBSearchValues )。 虽然这对初始加载会有性能损失,但是在后续search中可能比在一个或多个文件上进行自定义二进制search更好。

正如我在评论中所说的那样 – 这不难testing,您可以将大型数据库加载到Core Data存储中,并创build一个testing应用程序,以查看结果返回的速度。

我说Core Data over SQLite–因为它是针对平台进行优化的(尽pipe它使用SQLite作为存储介质),编写返回值并显示它们的代码更容易。

编辑添加

我创build了一个样本项目,加载了11条logging和400,000条logging的数据集。 这在iOS 5上使用了Core Data。

在我的iPad2上testing(是的2)

search时间在3-8毫秒(0.003-0.008秒)之间变化,在较小和较大的数据集之间没有可观的差异。

这是未经优化的代码,在debugging模式下运行,不是为了任何性能增强而编写的 – search谓词是在每次search时创build的,而不是caching的,例如没有线程。

40万条logging的数据存储大小为17.2 MB,所以即使是较大的4.5米logging也可以很容易地放在iPad上。

在iOS上将这些数据加载到内存中是一件不容易的事情。

你应该使用SQLLite。 这就是它所做的,你不会做更好的手动文件IO代码。

Interesting Posts