为什么c# Ado.net比实体框架6.1.3慢?

本文关键字:框架 实体 Ado net 为什么 | 更新日期: 2023-09-27 18:16:39

我写了一些代码来比较c# Ado的性能。Net和实体框架6.1.3。我正在调用一个存储过程,该过程返回大约20,000条员工记录,然后将此数据映射到"Person"对象列表中。然后我对这段代码进行了1000次迭代,并计算了平均时间。

时间:

  • Ado Net: 638 ms

  • 实体框架:544 ms

令我惊讶的是,adonet比Entity Framework慢了大约100毫秒。

Ado。网络代码:

    //GetAllPersons is a stored proc hosted in Local DB instance
    var adapter = new SqlDataAdapter("GetAllPersons", conn);
    adapter.Fill(dt);
    //Using Fast member library
    var accessor = TypeAccessor.Create(typeof(Person));
    MemberSet members = accessor.GetMembers();
    var list = new List<Person>();
    foreach(DataRow row in dt.Rows)
    {
        var person = new Person();
        foreach (var member in members)
        {
            if (row[member.Name] != DBNull.Value)
            {
                accessor[person, member.Name] = row[member.Name];
            }
        }
        list.Add(person);
    }
实体框架:

        var context = new AdventureWorks2012Entities1();
        List<Person> list = context.GetAllPersons().ToList();

使用SQL适配器加载Datatable的部分代码占用了大部分时间。我尝试使用SQL Datareader代替,但它甚至更糟。我是不是漏掉了什么,因为我以为是普通的阿多。Net应该比实体框架更快吗?

为什么c# Ado.net比实体框架6.1.3慢?

您写道您尝试过SqlDataReader,但它甚至更慢。它应该是最快的,但由于你没有展示你的代码,我们无法提供建议。但这里有一些通用的技巧:

1。

与其使用reader["column_name"],不如获取列序数,然后使用它。例如:

using (var reader = command.ExecuteReader())
{
  int col1Ordinal = reader.GetOrdinal("Column1");
  int col2Ordinal = reader.GetOrdinal("Column2");
  while (reader.Read())
  {
    int col1 = (int)reader[col1Ordinal];
    string col2 = (string)reader[col2Ordinal];
    // do something with col1 and col2's values
  }
}

2。避免多次获取

索引操作符是一个方法调用,因此避免对同一个值多次调用。在SqlDataAdapter代码中,您写入

if (row[member.Name] != DBNull.Value)
{
  accessor[person, member.Name] = row[member.Name];
}

如你所见,你调用了两次row[member.Name]。相反,应该只获取一次,然后重用

值。
object value = row[member.Name];
if (value != DBNull.Value)
{
  accessor[person, member.Name] = value;
}

3。避免反射

我从来没有听说过TypeAccessorMemberSet。通过快速搜索,它似乎来自一个名为fast-member的库。即使它比。net的内置反射快,我也怀疑它到底有多快。我知道它可以显著减少您必须编写的代码量,特别是如果您的查询有许多列,这是很好的。但是,如果你试图优化性能,特别是如果你不满意你的代码的性能与实体框架相比,你应该删除依赖和测试性能差异是什么。

实体框架(EF)是基于Ado.Net;参见什么是实体框架?通过实体框架教程。因此,EF不能比纯Ado更快。净实现。

但是,您实现了一个不太理想的解决方案,使用循环中的循环和其他开销(例如使用反射)。我认为内部EF实现比这更聪明,并且可能利用上下文初始化而不是内部循环。

试试这个:在你的表中只有一个雇员,然后比较结果。EF可能更慢。