zoukankan      html  css  js  c++  java
  • 测试EF6.1.3和OrmLite性能

         公司原来用nhibernate,现在考虑要不要换一种ORM,于是找来了EF和ServiceStack.OrmLite。所以就产生了测试这三个性能的要求。对比三个ORM工具的性能,主要是对比ORM配置和启动速度;建表速度;插入行速度;修改行速度以及查询速度,删除用的比较少,就不测试了,还有发现EF貌似比nhibernate稍微快一些,就只测EF和ServiceStack.OrmLite了。

         测试表结构

        public class School
        {
            public Guid ID { get; set; }
            public string Name { get; set; }
            public int AllPersonCount { get; set; }
        }
        public class Person
        {
            public long ID { get; set; }
            public string Name { get; set; }
            public int Age { get; set; }
            public School InShool { get; set; }
        }

          测试项目

    1. 插入10个学校, 学校人数从1递增,名称相同为”SSS”
    2. 每个学校插入1000人,年龄从1递增,名字相同”PPP”,并返回ID
    3. 查询年龄大于30的人
    4. 更新3查询出的人的年龄到当前值加20
    5. 查询学校人数大于5的所有人
    6. 统计学校人数大于5的所有人的人数

          代码原则

    1. 尽量简洁
    2. 不能使用sql语句

      写测试代码

      nhibernate是由另一个家伙搞,我就写EF的测试代码。首先新建一个控制台应用程序,右键项目管理NuGet添加EF6.1.3。然后新建那两个表对应的类,接着就开始一个个写啦。下面每种的两个代码段上面的是EF的,下面的是ServiceStack.OrmLite的

      ORM配置及启动

    watch.Start();
    db = new TestContext();
    watch.Stop();
    Console.WriteLine("ORM配置及启动:" + watch.ElapsedMilliseconds);
    watch.Start();
    OrmLiteConfig.DialectProvider = SqlServerDialect.Provider;
    string connStr = ConfigurationManager.ConnectionStrings["SSConnection"].ConnectionString;
    db = connStr.OpenDbConnection();
    watch.Stop();
    Console.WriteLine("ORM配置及启动:" + watch.ElapsedMilliseconds);

      建表

    watch.Restart();
    db.Database.Initialize(true);
    watch.Stop();
    Console.WriteLine("建表:" + watch.ElapsedMilliseconds);
    watch.Restart();
    db.CreateTable<School>();
    db.CreateTable<Person>();
    watch.Stop();
    Console.WriteLine("建表:" + watch.ElapsedMilliseconds);

      测试项目1

    db.Configuration.AutoDetectChangesEnabled = false;
    db.Configuration.ValidateOnSaveEnabled = false;
    watch.Restart();
    
    for (int i = 1; i < 11; i++)
    {
        db.School.Add(new School
        {
            ID = Guid.NewGuid(),
            Name = "SSS",
            AllPersonCount = i
        });
    }
    
    db.SaveChanges();
    watch.Stop();
    Console.WriteLine("测试项目1:" + watch.ElapsedMilliseconds);
    watch.Restart();
    var schools = new List<School>();
    
    for (int i = 1; i < 11; i++)
    {
        schools.Add(new School
        {
            ID = Guid.NewGuid(),
            Name = "SSS",
            AllPersonCount = i
        });
    }
    
    db.InsertAll(schools);
    watch.Stop();
    Console.WriteLine("测试项目1:" + watch.ElapsedMilliseconds);

      测试项目2

    watch.Restart();
    List<School> schools = db.School.ToList();
    
    schools.ForEach(o =>
    {
        for (int i = 1; i < 1001; i++)
        {
            db.Person.Add(new Person
            {
                Age = i,
                Name = "PPP",
                InShool = o
            });
        }
    });
    
    db.SaveChanges();
    watch.Stop();
    Console.WriteLine("测试项目2:" + watch.ElapsedMilliseconds);
    schools = db.LoadSelect<School>();
    watch.Restart();
    var students = new List<Person>();
    
    schools.ForEach(o =>
    {
        for (int i = 1; i < 1001; i++)
        {
            students.Add(new Person
            {
                Age = i,
                Name = "PPP",
                ShoolID = o.ID
            });
        }
    });
    
    db.InsertAll(students);
    watch.Stop();
    Console.WriteLine("测试项目2:" + watch.ElapsedMilliseconds);

      测试项目3

    db.Configuration.AutoDetectChangesEnabled = true;
    watch.Restart();
    List<Person> person = db.Person.Where(o => o.Age > 30).ToList();
    watch.Stop();
    Console.WriteLine("测试项目3:" + watch.ElapsedMilliseconds);
    watch.Restart();
    List<Person> persons = db.Select<Person>(x => x.Age > 30);
    watch.Stop();
    Console.WriteLine("测试项目3:" + watch.ElapsedMilliseconds);

      测试项目4

    watch.Restart();
    person.ForEach(o => o.Age += 20);
    db.SaveChanges();
    watch.Stop();
    Console.WriteLine("测试项目4:" + watch.ElapsedMilliseconds);
    watch.Restart();
    persons.ForEach(o => o.Age += 20);
    db.UpdateAll(persons);
    watch.Stop();
    Console.WriteLine("测试项目4:" + watch.ElapsedMilliseconds);

      测试项目5

    watch.Restart();
    List<Person> students = db.Person.AsNoTracking().Where(o => o.InShool.AllPersonCount > 5).ToList();
    watch.Stop();
    Console.WriteLine("测试项目5:" + watch.ElapsedMilliseconds);
    watch.Restart();
    students = db.Select(
        db.From<Person>()
            .Join<School>((p, s) => p.ShoolID == s.ID)
            .Where<School>(s => s.AllPersonCount > 5)
        );
    watch.Stop();
    Console.WriteLine("测试项目5:" + watch.ElapsedMilliseconds);

      测试项目6

    watch.Restart();
    int count = db.Person.Count(o => o.InShool.AllPersonCount > 5);
    watch.Stop();
    Console.WriteLine("测试项目6:" + watch.ElapsedMilliseconds);
    watch.Restart();
    long count = db.Count(
        db.From<Person>()
            .Join<School>((p, s) => p.ShoolID == s.ID)
            .Where<School>(s => s.AllPersonCount > 6)
        );
    watch.Stop();
    Console.WriteLine("测试项目6:" + watch.ElapsedMilliseconds);

      这里要说明一下的是测试项目5和6的人数大于5是说学校表的AllPersonCount大于5,而且那个字段并不是真的学生总人数,不会随学生的增加而增加,只是为了测试的。

      EF运行3次的截图如下:

      ServiceStack.OrmLite运行3次的截图如下:

      接下来要开大招了,学校从加10个改为加100个,这样的话学生就会从10000个增加到100000个,插入10万行的时候nhibernate直接顶不住了。

      EF运行3次的截图如下:

      ServiceStack.OrmLite运行3次的截图如下:

      需要说明的是数据库是mssql2008,并且程序和数据库都在本机,不同的电脑的性能不一样,数据库不一样也会影响测试的结果,所以大家如果要对比其他ORM工具的话,需要把多个程序在同一个电脑上运行,并且连接同一个数据库。通过对比可以发现,轻量级的OrmLite最快,EF和nhiberate差不多快,EF稍占优势。不过并发能力的话倒是还没测试过,不知道那个更好。

      示例代码下载

    TestEF6.1.3

    TestOrmLite

  • 相关阅读:
    ArcGIS Engine 中的多线程使用
    Arcgis栅格时序地图制作---时间轴动态展示多期影像
    R树空间索引
    R-Tree空间索引算法的研究历程和最新进展分析
    学生表、课程表、 成绩表 、教师表sql练习
    Mysql建表出现1005错误
    MySQL数据类型详解
    数据库操作语句类型(DQL、DML、DDL、DCL)简介
    Spring MVC标签<mvc: annotation-driven />小结 原
    EasyUI Menu 菜单
  • 原文地址:https://www.cnblogs.com/hambert/p/4389321.html
Copyright © 2011-2022 走看看