Dapper vs ADO.Net用反射哪个更快?

Adn*_*ikh 4 c# reflection ado.net dapper

我研究了Dapper和ADO.NET,并对两者进行了选择测试,发现有时ADO.NET比Dapper更快,有时会逆转.我知道这可能是数据库问题,因为我正在使用SQL Server.据说反射很慢,我在ADO.NET中使用反射.那么有谁能告诉我哪种方法最快?

这是我编码的.

  1. 使用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<MerchantProduct> lstMerProd = dr.MapToList<MerchantProduct>();
    List<MerchantPayment> lstMerPay = dr.MapToList<MerchantPayment>();
    
    if (lstMerProd != null || lstMerPay != null)
    {
        dashResp = new DashboardResponseModel();
        dashResp.MerchantProduct = lstMerProd == null ? new 
        List<MerchantProduct>() : lstMerProd;
        dashResp.MerchantPayment = lstMerPay == null ? new 
        List<MerchantPayment>() : lstMerPay;
    }
    
    dr.Close();
    
    }
    
    return dashResp;
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用Dapper

    DashboardResponseModel dashResp = null;
    
    var multipleresult = db.QueryMultiple("spGetMerchantDashboard", new { mid = 
    mid }, commandType: CommandType.StoredProcedure);
    var merchantproduct = multipleresult.Read<MerchantProduct>().ToList();
    var merchantpayment = multipleresult.Read<MerchantPayment>().ToList();
    
    if (merchantproduct.Count > 0 || merchantpayment.Count > 0)
    dashResp = new DashboardResponseModel { MerchantProduct = 
    merchantproduct, MerchantPayment = merchantpayment };
    
    return dashResp;
    
    Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 8

Dapper基本上跨越了ADO.NET作为一个非常薄的抽象 - 所以理论上它不能比编写良好的ADO.NET代码更快(尽管说实话:大多数人都写不出写得好的ADO.NET代码).

但是,它几乎无法区分 ; 假设您使用Dapper(不是任何位于其上的东西),那么它不包括任何查询生成,表达式树/ DSL解析,复杂模型配置或任何其他倾向于制作的东西完整的ORM更灵活但更昂贵.

相反:它只关注执行用户提供的查询和映射结果; 它的作用是MerchantProduct通过IL-emit 生成所有物化代码(如何映射到您的列)并在某处缓存.同样,它以相同的方式准备了大部分参数准备代码.因此,在运行时,它通常只是从缓存中获取两个委托实例并调用它们.

由于(RDBMS的延迟+查询执行成本+结果的网络带宽成本)的组合将远远高于从字典中提取两个代表的开销,我们基本上可以忽略该成本.

简而言之:您可以在此处测量显着的开销.

作为一个小的优化你的代码:宁愿AsList()ToList()避免创建副本.


Ami*_*shi 6

理论:

Dapper 是微 ORM 或数据映射器。它在内部使用 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 可能会更慢:

  1. 如果返回的数据结构足够大(这会增加映射时间),Dapper 会稍微慢一些。但是,这同样适用于 ADO.NET。如前所述,Dapper 的 mapper 部分进行了大量优化;所以它仍然是比代码中的手动映射更好的选择。此外,Dapper 提供了buffered参数;如果设置为false,Dapper 不会实现列表。它只是在迭代器中将每个项目交给您。请参阅@Marc对此答案的评论。

  2. Dapper 没有实现特定于提供者的功能,因为它是在IDbConnection. 在极少数情况下,这可能会影响性能。但是,如果您实现一个接口来告诉 Dapper 如何执行此操作,则可以完成此操作。

  3. Dapper 不支持准备报表。在极少数情况下,这可能是一个问题。阅读博客。

通过这种轻微而罕见的性能损失,您可以获得巨大的好处,包括强类型数据结构和更少且易于管理的代码。这真的是一个很大的收获。

网上有很多Dapper(与其他 ORM 和 ADO.NET)的性能比较统计数据;看看以防万一你有兴趣。