iOS开发中,最常见的数据持久化方式:
1、CoreData:苹果官方推荐的数据存储框架
2、FMDB:针对libsqlite3框架进行封装的三方,它以OC的方式封装了SQLite的C语言的API
今天博主针对这两种方式,从增、删、改、查四个方面进行了性能对比
首先,看下github上的情况:
使用CoreData很多人都会利用MagicalRecord来简化使用方式,这边github的截图仅作参考而已,并不体现CoreData和FMDB的真实使用量
附上github地址:
FMDB:https://github.com/ccgus/fmdb
MagicalRecord:https://github.com/magicalpanda/MagicalRecord
进入正题,先附上对比结果:
之前看过一篇性能对比的博客,结果显示FMDB在连续插入数据上的性能远远低于CoreData,导致此问题的原因应该是FMDB没有使用"事务"方式来插入,为此博主特地把插入方式分为事务方式和非事务方式,在CoreData上则表现为再for循环里面每次执行MR_saveToPersistentStoreAndWait 或者 for循环结束再执行MR_saveToPersistentStoreAndWait。
结果显示,FMDB除了在频繁插入数据且不使用"事务"方式时性能低于CoreData,其他方面数据都优于CoreData
附上代码:
插入数据:
NSDate* tmpStartData = [NSDate date];
int count = 1000;
for (int i = 0; i < count; i++) {
Student *entity = [Student MR_createEntity];
entity.name = [NSString stringWithFormat:@"%d",i];
entity.sex = 1;
entity.age = 20;
[[NSManagedObjectContext MR_defaultContext]MR_saveToPersistentStoreAndWait];
}
double deltaTime = [[NSDate date] timeIntervalSinceDate:tmpStartData];
_txtView.text = [NSString stringWithFormat:@"%@\n%@",_txtView.text,[NSString stringWithFormat:@"CoreData(多次保存)写入%d条数据耗时 = %f",count,deltaTime]];
tmpStartData = [NSDate date];
for (int i = 0; i < count; i++) {
Student *entity = [Student MR_createEntity];
entity.name = [NSString stringWithFormat:@"%d",i];
entity.sex = 1;
entity.age = 20;
}
[[NSManagedObjectContext MR_defaultContext]MR_saveToPersistentStoreAndWait];
deltaTime = [[NSDate date] timeIntervalSinceDate:tmpStartData];
_txtView.text = [NSString stringWithFormat:@"%@\n%@",_txtView.text,[NSString stringWithFormat:@"CoreData(一次性保存)写入%d条数据耗时 = %f",count,deltaTime]];
tmpStartData = [NSDate date];
[db open];
for (int i = 0; i < count; i++) {
[db executeUpdate:@"insert into 't_student'(name,age,sex) values(?,?,?)" withArgumentsInArray:@[[NSString stringWithFormat:@"%d",i],@20,@1]];
}
[db close];
deltaTime = [[NSDate date] timeIntervalSinceDate:tmpStartData];
NSLog(@"FMDB(非事务方式处理)写入%d条数据耗时 = %f",count,deltaTime);
_txtView.text = [NSString stringWithFormat:@"%@\n%@",_txtView.text,[NSString stringWithFormat:@"FMDB(一次性保存)写入%d条数据耗时 = %f",count,deltaTime]];
tmpStartData = [NSDate date];
[db open];
//1.开启事务
[db beginTransaction];
BOOL rollBack = NO;
@try {
for (int i = 0; i < count; i++) {
[db executeUpdate:@"insert into 't_student'(name,age,sex) values(?,?,?)" withArgumentsInArray:@[[NSString stringWithFormat:@"%d",i],@20,@1]];
}
} @catch(NSException *exception){
//3.在事务中执行任务失败,退回开启事务之前的状态
rollBack = YES;
[db rollback];
} @finally{
//4. 在事务中执行任务成功之后
rollBack = NO;
[db commit];
}
[db close];
deltaTime = [[NSDate date] timeIntervalSinceDate:tmpStartData];
_txtView.text = [NSString stringWithFormat:@"%@\n%@\n\n",_txtView.text,[NSString stringWithFormat:@"FMDB(事务方式处理)写入%d条数据耗时 = %f",count,deltaTime]];
查询数据:
NSDate* tmpStartData = [NSDate date];
NSArray *arr = [Student MR_findByAttribute:@"sex" withValue:@1];
double deltaTime = [[NSDate date] timeIntervalSinceDate:tmpStartData];
_txtView.text = [NSString stringWithFormat:@"%@\n%@",_txtView.text,[NSString stringWithFormat:@"CoreData查询到%ld条数据耗时 = %f",arr.count,deltaTime]];
tmpStartData = [NSDate date];
[db open];
FMResultSet *result = [db executeQuery:@"select * from 't_student' where sex = ?" withArgumentsInArray:@[@1]];
NSMutableArray *mArr = [NSMutableArray new];
while ([result next]) {
int age = [result intForColumn:@"age"];
[mArr addObject:@(age)];
}
[db close];
deltaTime = [[NSDate date] timeIntervalSinceDate:tmpStartData];
_txtView.text = [NSString stringWithFormat:@"%@\n%@\n\n",_txtView.text,[NSString stringWithFormat:@"FMDB查询到%ld条数据耗时 = %f",mArr.count,deltaTime]];
删除数据:
NSDate* tmpStartData = [NSDate date];
NSArray *arr = [Student MR_findByAttribute:@"sex" withValue:@1];
for (Student *entity in arr) {
[entity MR_deleteEntity];
}
[[NSManagedObjectContext MR_defaultContext]MR_saveToPersistentStoreAndWait];
double deltaTime = [[NSDate date] timeIntervalSinceDate:tmpStartData];
_txtView.text = [NSString stringWithFormat:@"%@\n%@",_txtView.text,[NSString stringWithFormat:@"CoreData删除所有数据耗时 = %f",deltaTime]];
tmpStartData = [NSDate date];
[db open];
[db executeUpdate:@"delete from 't_student' where sex = ?" withArgumentsInArray:@[@1]];
deltaTime = [[NSDate date] timeIntervalSinceDate:tmpStartData];
[db close];
_txtView.text = [NSString stringWithFormat:@"%@\n%@\n\n",_txtView.text,[NSString stringWithFormat:@"FMDB删除所有数据耗时 = %f",deltaTime]];
更新数据:
NSDate* tmpStartData = [NSDate date];
NSArray *arr = [Student MR_findByAttribute:@"sex" withValue:@1];
for (Student *entity in arr) {
entity.age = 21;
}
[[NSManagedObjectContext MR_defaultContext]MR_saveToPersistentStoreAndWait];
double deltaTime = [[NSDate date] timeIntervalSinceDate:tmpStartData];
_txtView.text = [NSString stringWithFormat:@"%@\n%@",_txtView.text,[NSString stringWithFormat:@"CoreData更新所有数据1个字段耗时 = %f",deltaTime]];
tmpStartData = [NSDate date];
[db open];
[db executeUpdate:@"update 't_student' set age = ? where sex = ?" withArgumentsInArray:@[@21,@1]];
deltaTime = [[NSDate date] timeIntervalSinceDate:tmpStartData];
[db close];
_txtView.text = [NSString stringWithFormat:@"%@\n%@\n\n",_txtView.text,[NSString stringWithFormat:@"FMDB更新所有数据1个字段耗时 = %f",deltaTime]];
附上Domo截图:
Demo github地址: https://github.com/zhengshengxi/ZSXCoreDataPKFMDB.git
博主技术能力有限,如本次评测中有考虑不周或者不恰当或者可优化的地方希望大神指出,谢谢!