公司原来用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 = ; i < ; 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 = ; i < ; 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 = ; i < ; 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 = ; i < ; 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 > ).ToList();
watch.Stop();
Console.WriteLine("测试项目3:" + watch.ElapsedMilliseconds);
watch.Restart();
List<Person> persons = db.Select<Person>(x => x.Age > );
watch.Stop();
Console.WriteLine("测试项目3:" + watch.ElapsedMilliseconds);

  测试项目4

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

  测试项目5

watch.Restart();
List<Person> students = db.Person.AsNoTracking().Where(o => o.InShool.AllPersonCount > ).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 > )
);
watch.Stop();
Console.WriteLine("测试项目5:" + watch.ElapsedMilliseconds);

  测试项目6

watch.Restart();
int count = db.Person.Count(o => o.InShool.AllPersonCount > );
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 > )
);
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

测试EF6.1.3和OrmLite性能的更多相关文章

  1. ormlite性能对比

    看了一下现在的android设备,性能都不差,就懒得直接用sqlite,直接上ORM框架把,上网搜了一圈,觉得androrm, ormlite 这两个不错,当然,还有点别的,这里就不多做介绍,竟然说明 ...

  2. PHP中测试in_array、isset、array_key_exists性能

    测试in_array.isset.array_key_exists性能.自己写的简易测试代码: ini_set('display_errors',true); error_reporting(E_AL ...

  3. 有谁知道什么工具测试IOS手机上APP的性能软件啊?

    有谁知道什么工具测试IOS手机上APP的性能软件啊?

  4. 性能测试--测试流程、APDEX、linux性能知识

    测试流程.APDEX.linux性能知识 一.性能测试流程: 整体流程:收集需求-->搭建测试环境-->设计性能测试场景-->开发测试脚本-->执行测试-->收集数据-- ...

  5. python环境测试MySQLdb、DBUtil、sqlobject性能

    python环境测试MySQLdb.DBUtil.sqlobject性能 首先介绍下MySQLdb.DBUtil.sqlobject: (1)MySQLdb 是用于Python连接Mysql数据库的接 ...

  6. 即使用ADO.NET,也要轻量级动态生成更新SQL,比Ormlite性能更高

    先上测试结果: //测试1000次针对同一个表同一个字段更新,比Ormlite平均快2.34倍 //生成SQL+ExecuteNonQuery Ormlite 倍数 //6513ms 15158ms ...

  7. 【Android测试】【第一节】性能——CPU

    ◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/5065083.html 前言 本来打算写完全部的自动化测试之 ...

  8. 测试canvas绘制旋转文字的性能

    canvas 绘制各种动画效果时,我们经常会使用画布旋转,使绘制上去的元素有旋转的效果. 最近在项目中碰到了很严重的性能问题,经常排查发现是因为绘制批量文字时使用了画布旋转,且每行文字的旋转角度是不一 ...

  9. 【Android测试】【第二节】性能——CPU时间片

    ◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/5143192.html 前言 第一节讲CPU的时候留下了一个 ...

随机推荐

  1. vim 使用技巧记录

    vim 使用技巧记录 1.批量注释与取消注释 命令格式:起始行号,结束行号s#^#//#g 例如: 注释代码3到15行,"//"可以是其他的"" :3,15s# ...

  2. MSDTC事务配置

    最近再用SSIS做数据归档,里面用到了分布式事务.在开发阶段是在一台计算机上运行只要是启动分布式服务就没什么问题,可是昨天把它部署到uat的时候遇到问题,错误信息是: 最后找到解决方案: 确认&quo ...

  3. day4(homework)

    第八单元 1) 将用户信息数据库文件和组信息数据库文件纵向合并为一个文件/1.txt(覆盖) 2) 将用户信息数据库文件和用户密码数据库文件纵向合并为一个文件/2.txt(追加) 3) 将/1.txt ...

  4. [BI项目记]-BUG创建

    BUG是在项目过程中以及运维过程中经常遇到的工作项.在处理每一个BUG的过程中,通过项目管理系统把BUG相应的内容纪录下来也是很重要的.这里将介绍如何通过TFS来完成BUG的创建工作. 首先我们来看B ...

  5. postgresql数据库备份和恢复

    PostgreSQL自带一个客户端pgAdmin,里面有个备份,恢复选项,也能对数据库进行备份 恢复(还原),但最近发现数据库慢慢庞大的时候,经常出错,备份的文件过程中出错的几率那是相当大,手动调节灰 ...

  6. JDK7和JDK8一些重要新特性

    jdk7新特性(部分) switch支持字符串 List AutoCloseable接口实现自动关闭,在try()中 新增获取环境信息的工具方法,getJavaHomeDir,getUserHomeD ...

  7. Zookeeper操作

    Zookeeper操作 注意搭建: 1.集群规模不小于3个节点 2.服务器之间系统时间要保持一致 1.搭建步骤: 1.解压安装包 2.设置zookeeper环境变量 3.修改配置文件————zoo.c ...

  8. jq插件制作(力推)

    http://www.cnblogs.com/Wayou/p/jquery_plugin_tutorial.html http://www.frontopen.com/1710.html

  9. 1.4 jQuery方法,JSON介绍

    jQuery方法: jQuery添加元素: append()方法: $("元素").append("追加内容"); prepend()方法: $("元 ...

  10. (转)java自带线程池和队列详细讲解 - CSDN过天的专栏

    一简介 线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的.在jdk1.5之后这一情况有了很大的改观.Jdk1.5之后加入了java.util ...