Dapper vs ADO.Net用reflection哪个更快?
我研究了Dapper和ADO.NET,并对两者进行了选择测试,发现有时ADO.NET比Dapper更快,有时会逆转。 我知道这可能是数据库问题,因为我正在使用SQL Server。 据说reflection很慢,我在ADO.NET中使用reflection。 那么有谁能告诉我哪种方法最快?
这就是我编码的内容。
-
使用ADO.NET
DashboardResponseModel dashResp = null; SqlConnection conn = new SqlConnection(connStr); try { SqlCommand cmd = new SqlCommand("spGetMerchantDashboard", conn); cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddWithValue("@MID", mid); conn.Open(); var dr = cmd.ExecuteReader(); List lstMerProd = dr.MapToList(); List lstMerPay = dr.MapToList(); if (lstMerProd != null || lstMerPay != null) { dashResp = new DashboardResponseModel(); dashResp.MerchantProduct = lstMerProd == null ? new List() : lstMerProd; dashResp.MerchantPayment = lstMerPay == null ? new List() : lstMerPay; } dr.Close(); } return dashResp;
-
使用Dapper
DashboardResponseModel dashResp = null; var multipleresult = db.QueryMultiple("spGetMerchantDashboard", new { mid = mid }, commandType: CommandType.StoredProcedure); var merchantproduct = multipleresult.Read().ToList(); var merchantpayment = multipleresult.Read().ToList(); if (merchantproduct.Count > 0 || merchantpayment.Count > 0) dashResp = new DashboardResponseModel { MerchantProduct = merchantproduct, MerchantPayment = merchantpayment }; return dashResp;
Dapper基本上跨越了ADO.NET作为一个非常薄的抽象 – 所以理论上它不能比编写良好的ADO.NET代码更快 (尽管说实话:大多数人都写不好写的ADO.NET代码)。
但是,它几乎无法区分 ; 假设您只使用Dapper(不是任何位于其上的东西),那么它不包括任何查询生成,表达式树/ DSL解析,复杂模型配置或任何其他倾向于制作的东西完整的ORM更灵活但更昂贵。
相反:它只关注执行用户提供的查询和映射结果; 它的作用是生成所有物化代码(如何将MerchantProduct
映射到您的列)通过IL-emit和缓存到某处。 同样,它以相同的方式准备了大部分参数准备代码。 因此,在运行时,它通常只是从缓存中获取两个委托实例并调用它们。
由于(RDBMS的延迟+查询执行成本+结果的网络带宽成本)的组合将远远高于从字典中提取两个代表的开销,我们基本上可以忽略该成本。
简而言之:您可以在此处测量显着的开销。
作为代码的次要优化:首选AsList()
到ToList()
以避免创建副本。
理论:
Dapper是micro-ORM或Data Mapper。 它内部使用ADO.NET。 此外,Dapper将ADO.NET数据结构(例如DataReader
)映射到您的自定义POCO类。 因为这是Dapper做的额外工作 ,理论上它不能比ADO.NET快。
以下是从其中一条评论 (@MarcGravell)复制以下答案:
它不能比它所处的原始API更快; 但是,它可能比典型的ADO.NET消费代码更快 – 大多数消耗ADO.NET的代码往往写得很糟糕,效率低下等等; 甚至没有让我开始使用
DataTable
🙂
假设在比较时ADO.NET以优化的方式正确使用。 否则,结果可能相反; 但这不是ADO.NET的错。 如果ADO.NET使用不正确,它可能比Dapper表现不佳。 这是在使用ADO.NET直接绕过Dapper时发生的情况。
实际的:
与ADO.NET相比,大多数情况下的Dapper表现相同(可忽略不计)。 Dapper内部实现了许多针对其范围内的ADO.NET推荐的优化。 此外,它强制许多良好的ADO.NET编码实践最终提高性能(和安全性)。
由于映射是Dapper的核心部分,因此通过使用IL进行了大量优化。 这使得Dapper比在代码中手动映射更好。
请参阅此博客,其中介绍了如何发明Dapper以及如何针对性能进行优化: https : //samsaffron.com/archive/2011/03/30/How+I+learned+to+stop+worrying+and+write+my +拥有+ ORM
在以下场景中,Dapper可能会变慢:
-
如果返回的数据结构足够大(这会增加映射时间),Dapper会稍微慢一些。 但是,对于ADO.NET也是如此。 如前所述,Dapper的mapper部分已经过优化; 所以它仍然是比代码中的手动映射更好的选择。 此外,Dapper提供
buffered
参数; 如果设置为false
,则Dapper不会实现列表。 它只是在迭代器中将每个项目移交给您。 请参阅@Marc对此答案的评论。 -
Dapper没有实现特定于提供程序的function,因为它是通过
IDbConnection
编写的。 在极少数情况下,这可能会达到性能。 但是,如果您实现一个接口来告诉Dapper如何执行此操作,则可以执行此操作。 -
Dapper不支持准备声明。 在极少数情况下这可能是一个问题。 阅读此博客。
有了这种轻微且罕见的性能,您将获得巨大的好处,包括强类型数据结构和更少且易于管理的代码。 这真是一大收获。
网上有很多Dapper(与其他ORM和ADO.NET)的性能比较统计数据 ; 如果您有兴趣,请查看。
- ADO.NET或Linq to SQL?
- 用于x64应用程序的Microsoft.ACE.OLEDB.12.0驱动程序 – 如何使其与x86 MS Office一起安装?
- 使用ODP.NET按名称绑定查询参数
- 为什么要使用Dapper? 任何人都可以评论Dapper Vs ADO.NET优点和缺点
- SQL Server中的DateTime问题
- 从ADO.NET确定SQL Server的版本
- ADO.NET中断开连接方法的确切含义是什么
- 如何通过ADO.NET/C#使用Array / Table参数到Oracle(ODP.NET 10g)?
- 为什么在C#时分号不能放在OracleCommand的CommandText中