美文网首页天生不是作曲家iOS技术点iOS开发技术部落
Coredata和FMDB性能对比,原来差距这么大

Coredata和FMDB性能对比,原来差距这么大

作者: 梦想飞的鱼1 | 来源:发表于2016-09-17 16:10 被阅读1769次

    对于这两个持久化框架一直存在争议,公司里的项目一直都是会用coredata,一直对coredata印象还不错,再加上MagicalRecord对coredata的封装,使用起来就更简单了。FMDB用的很少,只知道对数据库操作都是手写sql语句执行,听起来性能应该更好,所以特意来对比一下。

    测试过程很简单,就对比了个操作
    1:在一个空表(6个字段)插入十万条数据
    2:更新十万数据的其中一个字段

    Coredata

    用coredata怎么能少得了MagicalRecord框架

    • 集成MagicalRecord
      使用cocoapods集成
    • 创建模型文件和实体
      这个表就6个字段


      QQ20160917-9@2x.png
    • 生成实体类


      QQ20160917-10@2x.png
    • 初始化数据库
      在AppDelegate.m添加如下代码
     - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        
        [MagicalRecord setDefaultModelNamed:@"Model.momd"];
        [MagicalRecord setupCoreDataStackWithStoreNamed:@"coredataDemo.db"];
        return YES;
    }```
    - 插入数据
    点击屏幕的时候执行
    

    NSLog(@"开始存储");
    [MagicalRecord saveWithBlock:^(NSManagedObjectContext * _Nonnull localContext) {
    for (int i=0; i<100000; i++) {
    User *user=[User MR_createEntityInContext:localContext];
    user.id=1000+i;
    user.name=[NSString stringWithFormat:@"ygc%d",i];
    user.mobilephone=@"13888886666";
    user.address=@"北京天安门广场101北京天安门广场101北京天安门广场101北京天安门广场101北京天安门广场101";
    user.age=arc4random_uniform(10)+20;
    user.gender=i%2;
    }
    } completion:^(BOOL contextDidSave, NSError * _Nullable error) {
    NSLog(@"结束存储");
    }];

    查看本地数据库,验证数据是否插入成功
    
    ![QQ20160917-2@2x.png](https://img.haomeiwen.com/i433584/1c8793939f342c41.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600)
    
    结果如下,耗时3.6秒
    ![QQ20160917-1@2x.png](https://img.haomeiwen.com/i433584/c4cd4bd57cbaa75d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600)
    - 更新数据
    将address字段更新,全表1000数据
    

    NSLog(@"开始更新");
    [MagicalRecord saveWithBlock:^(NSManagedObjectContext * _Nonnull localContext) {
    NSArray *users=[User MR_findAllInContext:localContext];
    if(users)
    {
    for (User *user in users) {
    user.address=@"上海东方明珠101上海东方明珠101上海东方明珠101上海东方明珠101上海东方明珠101上海东方明珠101";
    }
    }
    } completion:^(BOOL contextDidSave, NSError * _Nullable error) {
    NSLog(@"结束更新");
    }];

    结果如下,耗时4.8秒,由于coredata是面对对象的数据库,所以必须先把数据查出来,然修改对象的值,再提交保存。所以更新的过程多了一个查询的耗时
    ![QQ20160917-3@2x.png](https://img.haomeiwen.com/i433584/215af0ccfd3bf524.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    ###FMDB
    - 集成FMDB
    使用cocoapods集成
     pod 'MagicalRecord', '~> 2.3.2'
    - 初始化数据库并建表
    

    -(void)setUpDatabase
    {
    if(!_db)
    {
    NSString *path=[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"fmdb.db"];
    FMDatabase *db=[FMDatabase databaseWithPath:path];
    if([db open])
    {
    _db=db;
    [self createTables];
    }
    }
    }

    -(void)createTables
    {
    NSString *query=@"CREATE TABLE USER ( id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age INTEGER, gender INTEGER, address VARCHAR, mobilphone VARCHAR )";
    if([self.db executeUpdate:query])
    {
    NSLog(@"建表成功");
    }
    else
    {
    NSLog(@"建表失败");
    }
    }

    - 插入操作
    和上面一样,插入十万条数据,内容一样
    ```-(void)insert
    {
        NSLog(@"开始插入");
        for (int i=0; i<100000; i++) {
            NSString *name=[NSString stringWithFormat:@"ygc%d",i];
            NSString *mobilephone=@"13888886666";
            NSString *address=@"北京天安门广场101北京天安门广场101北京天安门广场101北京天安门广场101北京天安门广场101";
            NSUInteger age=arc4random_uniform(10)+20;
            NSUInteger gender=i%2;
            
            BOOL succes= [[DBTool sharedInstance].db executeUpdateWithFormat:@"insert into USER(name,age,gender,address,mobilphone) values (%@,%d,%d,%@,%@)",name,age,gender,address,mobilephone];
        }
        
        NSLog(@"结束插入");
    }
    

    执行结果如下,耗时68秒


    QQ20160917-6@2x.png
    • 更新操作
      代码如下
    -(void)update
    {
        //开始更新
        NSLog(@"开始更新");
        [[DBTool sharedInstance].db executeUpdateWithFormat:@"update USER set address=%@",@"上海东方明珠101上海东方明珠101上海东方明珠101上海东方明珠101上海东方明珠101上海东方明珠101"];
        NSLog(@"结束更新");
    }
    

    执行结果如下,耗时0.3秒,由于直接对表字段操作,所以速度很快


    QQ20160917-7@2x.png

    结果统计

    QQ20160917-5@2x.png

    对比结果下来,从性能上讲,也没有绝对的好与差,得看实际项目使用情况,并且还有优化的空间。不过从代码维护成本和学习成本来讲的话,还是coredata简单些(入门级别),语法上也很好接受。我倾向coredata还有一个很好的功能是coredata可以监听一个表的数据变化(NSFeatchResultController),是插入还是删除,还是修改,配合tableView很好做一些动画。不知道FMDB有没有这样的功能,还是要自己手动实现?

    相关文章

      网友评论

      • 9f8e2bb5d71b:FMDB 试着采用事务去插入10万条数据,相信你会发现很美好
      • 给你快乐:以前一直用的FMDB,看你的文章想学习一下MagicalRecord,求指点啊
        梦想飞的鱼1:@给你快乐 简书里有很多相关的文章,认真看几篇就入门了,然后在实际的项目中慢慢提高
      • 给你快乐:今天更新了Xcode8.0,,在生成实体类这里卡住了,这里新建出来怎么是以.swift结尾的两个文件? 我的 demo使用OC来写的,新建出来Swift版本的文件是怎么搞得?新手求教!!!
      • ce0c424a0fb8:以前从事的是Android开发,最近刚转ios,在Android开发中,数据库表的写操作诚如楼上所说的,如果是批量操作,就需要开启事务,效率会高很多倍;在读操作方面,如果在建表的时候针对频繁查询的字段建立索引,那读的效率也是会高很多倍的,您可以查看一下sqlite的语法
        梦想飞的鱼1:@地上喷洒不了 嗯,我会更深入了解FMDB
      • 掂吾掂:首先非常感谢作者对这两个东西的性能做出的性能分析...但是我希望作者能更加深入对比一下,所以冒昧发言..
        (1)就像2楼所说的,为什么插入100000条数据的时候会那么慢,那是因为你提交100000次事务,而一次事务提交是非常耗时,所以如果你换成一次事务提交,结果一定会让你觉得惊讶..
        (2)性能的比较不能以简单的单表操作作为依据结果...说得直白一点就是,如果现在有两张表,分别是某市的学校表以及学生表,假如学校表数据有500条,但是学生表数据有200000条,要求你查出某一个学校总有多少学生,这个时候你再用coredate和fmdb再进行一次对比(其实说白了就是在相同环境下对:增删改查 这四个操作进行全面的对比)..这样的话,我觉得会更有说服力..毕竟做任何性能分析都要针对不同的业务需求,选择最好的解决方案..
        所以还是希望作者能够再次完善一下吧....
        老猿人lin:我们项目就是fmdb 插入时候 优化处理也是 减少插入事物数 缓存列表数据 50条一插
        梦想飞的鱼1:@掂吾掂 谢谢你的回复和指正,我会更深入了解,然后写出更有深度的文章
        me007:@掂吾掂 很中肯
      • 山是水的故事:这是你的用法问题,sqlite你用事务试试,绝对比coredata快
        梦想飞的鱼1:@山是水的故事 谢谢指点
        梦想飞的鱼1:谢谢,我试试
        文兴:@山是水的故事 +1,orm框架一定会损失性能,sqlite纯数据库操作不可能比coredata慢

      本文标题:Coredata和FMDB性能对比,原来差距这么大

      本文链接:https://www.haomeiwen.com/subject/bqfwettx.html