Mego(1) - NET中主流ORM框架性能对比
从刚刚开始接触ORM到现在已有超过八年时间,用过了不少ORM框架也了解了不少ORM框架,看过N种关于ORM框架的相关资料与评论,各种言论让人很难选择。在ORM的众多问题中最突出的问题是关于性能方面的问题,因此我在看了国外的一遍文章(Dapper vs Entity Framework vs ADO.NET Performance Benchmarking)后受到启发,在这个文章的基础上扩展了测试用例分享给大家。
模型准备
用于测试是模型是基于一个订单系统,如下图所示,主要有客户、产品、仓库、订单及订单明细。其中数据表之前的关系从图中可以看出,此外产品、订单明细是自增列,仓库是两个主键构成的复合主键表。虽然只有5张表,但是已经包含了数据表的常用情况。

数据初始化
我们使用以上代码创建数据库,初始化数据表结构,生成测试数据,生成数据量如下表所示。
static void InitialDatabase()
{
using (var ef = new Models.EFContext())
{
if (!ef.Database.Exists())
{
ef.Database.Create(); using (var db = new Models.MegoContext())
{
db.InitialTable();
}
}
}
using (var db = new Models.MegoContext())
{
db.InitialData();
}
}
| 表名 | 说明 | 行数 |
| Customers | 客户表 | 10000 |
| Products | 产品表 | 9000 |
| Warehouses | 仓库表 | 30176 |
| Orders | 订单表 | 100000 |
| OrderDetails | 订单明细 | 600271 |
这些数据量已经快接近一个小型系统的数据量了,如果需要到本地执行,请将App.config文件中的连接字符串改成自己的数据库名直接运行即可。
测试用例说明
目前参与测试的框架如下:
本测试中的例子不仅仅限定于目前指定的这几种框架,这里定义了一个接口,如果想加入更多测试框架可以参考代码自行加入。
/// <summary>
/// 性能测试项目
/// </summary>
public interface IPerformanceTest
{
/// <summary>
/// 框架名称。
/// </summary>
string Framework { get; }
/// <summary>
/// 随机获取一个客户
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
long GetCustomerById(int id);
/// <summary>
/// 随机获取一个订单的所有明细
/// </summary>
/// <param name="orderId"></param>
/// <returns></returns>
long GetDetailsByOrder(int orderId);
/// <summary>
/// 随机获取一个订单及所有明细
/// </summary>
/// <param name="orderId"></param>
/// <returns></returns>
long GetOrderAndDetails(int orderId);
/// <summary>
/// 插入离散的N个客户。
/// </summary>
/// <returns></returns>
long InsertDiscreteCustomers(Customer[] customers);
/// <summary>
/// 插入离散的N个产品,自增主键。
/// </summary>
/// <returns></returns>
long InsertDiscreteProducts(Product[] products);
/// <summary>
/// 更新离散的N个客户。
/// </summary>
/// <returns></returns>
long UpdateDiscreteCustomers(Customer[] customers);
/// <summary>
/// 删除离散的N个明细。
/// </summary>
/// <returns></returns>
long DeleteDiscreteDetails(OrderDetail[] details);
/// <summary>
/// 删除离散的N个仓库,多主键。
/// </summary>
/// <returns></returns>
long DeleteDiscreteWarehouses(Warehouse[] warehouses);
}
我们主要有如下表几项测试(输出标题用于在结果中显示):
| 方法名 | 每次的测试量 | 输出标题 | 测试说明 |
| GetCustomerById | 随机查询100次。 | SELECT1 | 随机用主键获取指定客户数据。 |
| GetDetailsByOrder | 随机查询100次。 | SELECT2 | 随机用订单主键获取相关的订单明细数据。 |
| GetOrderAndDetails | 随机查询100次。 | SELECT3 | 随机用订单主键获取当前订单及所有订单明细数据。 |
| InsertDiscreteCustomers | 插入500条数据。 | INSERT1 | 插入指定数量的客户。 |
| InsertDiscreteProducts | 插入500条数据。 | INSERT2 | 插入指定数量的产品(产品的主键是自增列的)。 |
| UpdateDiscreteCustomers | 更新500条数据。 | UPDATE | 更新指定数量的客户。 |
| DeleteDiscreteDetails | 删除500条数据。 | DELETE1 | 删除指定数量的订单明细。 |
| DeleteDiscreteWarehouses | 删除500条数据。 | DELETE2 | 删除指定数量的仓库(仓库是复合主键)。 |
这里我们已经测试一个框架的增删改查,单个主键、复合主键、自增主键都有覆盖。为了公平我们将按顺序执行每个框架的测试,然后再重复执行多次,以下为测试运行代码,我们将忽略第一轮的运行结果。
List<TestResultItem> results = new List<TestResultItem>();
for (int i = ; i < TestSumCount + ; i++)
{
foreach (var framework in frameworks)
{
foreach (var p in insertProducts) p.Id = ;
var item = new TestResultItem(framework)
{
Convert.ToInt64(Enumerable.Range(,TestSelectCount1).Sum(a=>
framework.GetCustomerById(r.Next(customeIds.Item1, customeIds.Item2))
)),
Convert.ToInt64(Enumerable.Range(,TestSelectCount2).Sum(a=>
framework.GetDetailsByOrder(r.Next(orderIds.Item1, orderIds.Item2))
)),
Convert.ToInt64(Enumerable.Range(,TestSelectCount3).Sum(a=>
framework.GetOrderAndDetails(r.Next(orderIds.Item1, orderIds.Item2))
)),
framework.InsertDiscreteCustomers(insertCustomes),
framework.InsertDiscreteProducts(insertProducts),
framework.UpdateDiscreteCustomers(updateCustomes),
framework.DeleteDiscreteDetails(deleteDetails),
framework.DeleteDiscreteWarehouses(deleteWarehouse),
};
if (i > )
{
results.Add(item);
}
}
}
测试结果
如下图所示为测试的结果,本次测试针对 每个框架运行了4次,结果中首先输出了每个框架每一次的运行结果,在最后的汇总中输出了所有框架的平均用时。

结果分析
首先我们需要强调的是以上测试忽略了一些先进ORM框架的优势,例如批量插入自增列数据时,所生成的编号会返回到原对象中。从如上图的测试结果可以看出在查询方面各个框架都是比较接近的,不过会随着数据量升高这个差异会升高,在插入、更新及删除操作中就差别比较大了。主要原因是在批量提交中各个框架是逐个语句提交,还是组合批量提交的差别,这里主要是实现SQL语句的不同所产生的差异。在查询方面ADO.NET+AutoMapper是性能最高的,这个没有争议,如果有疑问可以参考开头所发的例子中,本文没有测试这个项目是因为修改操作实现不理想。
这里需要补充一下,从上面的测试结果来看SqlSugar的插入和删除比其他框架要高很多,其实这是有安全代价的,因为该框架是直接将值生成在SQL语句中的如下图所示,所以使用者需要在SQL注入方面注意一下。

后计
本文只把测试结果显示出来,没有结出任何结论,有兴趣的朋友可以从 Github 上下载代码来运行查看结果,后续还会持续更新加入更多框架进行测试。
Mego(1) - NET中主流ORM框架性能对比的更多相关文章
- 细数.NET 中那些ORM框架 —— 谈谈这些天的收获之一
细数.NET 中那些ORM框架 —— 谈谈这些天的收获之一(转) ADO.NET Entity Framework ADO.NET Entity Framework 是微软以 ADO.N ...
- Django中的ORM框架使用小技巧
Django中的ORM框架使用小技巧 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Django对各个数据提供了很好的支持,包括PostgreSQL,MySQL,SQLite ...
- [java]序列化框架性能对比(kryo、hessian、java、protostuff)
序列化框架性能对比(kryo.hessian.java.protostuff) 简介: 优点 缺点 Kryo 速度快,序列化后体积小 跨语言支持较复杂 Hessian 默认支持跨语言 较慢 Pro ...
- 6 大主流 Web 框架优缺点对比:15篇前端热文回看
摘自:http://blog.csdn.net/VhWfR2u02Q/article/details/78993079 注:以下文章,点击标题即可阅读 <6 大主流 Web 框架优缺点对比> ...
- sqlsugar freesql hisql 三个ORM框架性能测试对比
hisql与目前比较流行的ORM框架性能测试对比 总体测试结果 插入记录数 hisql(耗时) sqlsugar(耗时) freesql(耗时) 5条 0.0107秒 0.0312秒 0.02675秒 ...
- Mysql中Union和OR性能对比
博客已搬家,更多内容查看https://liangyongrui.github.io/ Mysql中Union和OR性能对比 在leetcode上看到一篇文章,整理一下 参考:https://leet ...
- Mego(2) - NET主流ORM框架分析
接上文我们测试了各个ORM框架的性能,大家可以很直观的看到各个ORM框架与原生的ADO.NET在境删改查的性能差异.这里和大家分享下我对ORM框架的理解及一些使用经验. ORM框架工作原理 典型ORM ...
- 主流PHP框架性能评测 (引用)
主要涉及到的框架有 CodeIgniter 老品牌易用性框架yaf 鸟哥用c写的php扩展,高性能框架yii 自动生成代码(gii)laravel 号称最优雅的框架swoole framework 支 ...
- “造轮运动”之 ORM框架系列(二)~ 说说我心目中的ORM框架
ORM概念解析 首先梳理一下ORM的概念,ORM的全拼是Object Relation Mapping (对象关系映射),其中Object就是面向对象语言中的对象,本文使用的是c#语言,所以就是.ne ...
随机推荐
- MongoDB 搭建文件存储的方案
用云的话,节省你开发成本,快速上线,数据比较安全.缺点是一旦用了他们的,形成习惯以后,数据想迁移就会比较麻烦,你会越来越依赖,而且规模上去以后价格并不低.早年自己做的话,你需要实现分布式文件系统,这个 ...
- 面向对象设计模式_生成器模式详解(Builder Pattern)
首先提出一个很容易想到应用场景: 手机的生产过程:手机有非常多的子件(部件),成千上万,不同品牌的手机的生产过程都是复杂而有所区别的,相同品牌的手机在设计上也因客户需求多样化,大到型号,小到颜色,是否 ...
- android studio运行的时候出现Unable to obtain debug bridge错误的解决办法
先贴上我百度的: 首先利用win+R,输入cmd,并且输入命令好来到:cd D:\Android\sdk\platform-tools\(这个是我的adb.exe目录,你的可以自行搜索)然后输入:ad ...
- canvas描绘渐变的矩形
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- Windows Server 2019 预览版介绍
在Windows server 2012.Windows server 2016还未完全普及的情况下,昨天Windows Server团队宣布Windows Server 2019将在2018年的下半 ...
- Centos7数据实时同步
Rsync+inotify 功能要求 通过rsync+inotify将数据库指定目录实时同步到备份服务器. 环境说明 M:192.168.10.11 数据库服务器 S:192.168.10.13 备份 ...
- C语言第六次作业--数据类型
一.PTA实验作业 题目1,简单计算器: 1. 本题PTA提交列表 2. 设计思路 定义操作数num1,num2,结果result=0.运算符ch. 输入num1 while (ch=getchar( ...
- PAT-L2-007-gplt真题
题目分析: 1. 首先,题目说一个家庭有孩子爸爸妈妈等几辈人,可以利用并查集将一个家庭里的所有人变成一个集合: 2. 刚好题目的目的也是这样,输出的是一个家庭人数,人均房产面积,人均房产套数等: 3. ...
- Docker学习笔记(一)
什么是Docker? 1.基于Go语言开发的云开源项目,Docker的主要目标是通过对应用组件的 封装,分发,部署,运行等生命周期的管理,达到应用组件级别的 一次封装,到处运行. 2.可以将Docke ...
- 【jQuery】 JQ和HTML以及JQ遍历元素
JQ & HTML JQ作为一个JS库,很好地继承了JS和HTML互动的特点,并且还给出了包装得更好,操作层次更高的方法.和之前JQ的内容一样,方法的表现形式是$(selector).acti ...