Performance NHibernate与ADO.NET的性能比较

Performance NHibernate与ADO.NET的性能比较,performance,nhibernate,orm,fluent-nhibernate,Performance,Nhibernate,Orm,Fluent Nhibernate,我已经评估了NHibernate和ADO.NET的性能。我创建了一个测试应用程序,它有一个包含75000条记录的Employee表。当我尝试使用NHibernate获取数据时,与ADO.NET相比速度非常慢,大约290%(大约)慢 NHibenrnate绑定75000条记录的平均性能为2535毫秒。 ADO.net绑定75000条记录的平均性能为867毫秒 我可以理解NHibernate是ADO.NET的包装器,但您不能支付300%的检索费用 我们从互联网上尝试了NHibernate的优化技巧。

我已经评估了NHibernate和ADO.NET的性能。我创建了一个测试应用程序,它有一个包含75000条记录的Employee表。当我尝试使用NHibernate获取数据时,与ADO.NET相比速度非常慢,大约290%(大约)慢

NHibenrnate绑定75000条记录的平均性能为2535毫秒。
ADO.net绑定75000条记录的平均性能为867毫秒

我可以理解NHibernate是ADO.NET的包装器,但您不能支付300%的检索费用

我们从互联网上尝试了NHibernate的优化技巧。这里有一些

  • 无状态会话的使用
  • 命名查询的使用
  • 会话刷新
  • 使用存储过程
  • 使用重新编译选项
  • 根据我的经验,在内存中构建对象时,时间正在消耗。此外,从探查器中的NHibernate和SQL触发的查询也存在差异。如果一次又一次地执行,则不会产生任何差异

    从员工中选择ID、姓名、加入日期、出生日期、部门ID、状态:Duration 516 选择此项。ID为ID2\u 0\u,名称为Name2\u 0\u,加入日期为DateOfJoin 2\u 0\u,出生日期为DateOfBirth2\u 0\u,部门ID为部门ID2\u 0\u,dbo状态为Status2\u 0。员工此:持续时间1538

    请建议任何其他提高性能的机制。使用ORM时,理想的性能差异应该是什么

    请查找下面的代码

    //Employee Class
    public class Employee
    {
        public virtual int ID { get; set; }
        public virtual string Name { get; set; }
        public virtual DateTime DateOfJoin { get; set; }
        public virtual DateTime DateOfBirth { get; set; }
        public virtual string DepartmentID { get; set; }
        public virtual string Status { get; set; }
    }
    
    //NHibernate Mapping
    public EmployeeMap()
    {            
        Table("Employee");
        Id(p => p.ID).GeneratedBy.Increment();
        Map(p => p. Name);
        Map(p => p. DateOfJoin);
        Map(p => p. DateOfBirth);
        Map(p => p. DepartmentID);
        Map(p => p. Status);                    
    }
    //Building Session Factory
    public static ISessionFactory SessionFactory
        {
           get
            {
                if (_sessionFactory == null)
                {
                    _sessionFactory = Fluently.Configure()
                    .Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("Connection")))
        .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Employee>())                    
                                      .BuildSessionFactory();
                }
                return _sessionFactory;
            }
        }
    
    //Fetching data using CreateQuey
    using (IStatelessSession session = SessionManager.SessionFactory.OpenStatelessSession())
    {
      IList<Employee> lstEmployee = session.CreateCriteria< Employee >().List<Employee>();               
    return lstEmployees.ToList<Employee>();
    }
    
    //Fetching data using Create Query
    using (IStatelessSession session = SessionManager.SessionFactory.OpenStatelessSession())
          {
    IList<Employee> lstEmployee = session.CreateQuery("from Employee "). List<Employee>();               
    return lstEmployees.ToList<Employee>();
       }
    
    //Fetching Data using ADO.net
    DataTable dtEmployees = /*Data is fetched from ADO.net using SQL Query*/;
            List<Employee> lstEmployee = new List<Employee>();
    
            foreach (DataRow dr in dtEmployees.AsEnumerable())
            {
                Employee employee = new Employee
                {
                    ID = dr.Field<int>("ID"),
                    Name = dr.Field<decimal>("Name"),
                    DateOfJoin = dr.Field<int>("DateOfJoin"),
                    DateOfBirth = dr.Field<int>("DateOfBirth"),
                    DepartmentID = dr.Field<int>("DepartmentID"),
                    Status = dr.Field<DateTime>("Status"),
                };
                lstEmployee.Add(Employee);
    
    //员工类
    公营雇员
    {
    公共虚拟整数ID{get;set;}
    公共虚拟字符串名称{get;set;}
    公共虚拟日期时间DateOfJoin{get;set;}
    公共虚拟日期时间出生日期{get;set;}
    公共虚拟字符串DepartmentID{get;set;}
    公共虚拟字符串状态{get;set;}
    }
    //NHibernate映射
    公共雇员地图()
    {            
    表(“员工”);
    Id(p=>p.Id).GeneratedBy.Increment();
    地图(p=>p.名称);
    Map(p=>p.DateOfJoin);
    Map(p=>p.出生日期);
    地图(p=>p.部门ID);
    Map(p=>p.状态);
    }
    //建筑会话工厂
    公共静态ISessionFactory会话工厂
    {
    得到
    {
    if(_sessionFactory==null)
    {
    _sessionFactory=fluntly.Configure()
    .Database(MsSqlConfiguration.MsSql2008.ConnectionString(c=>c.FromConnectionStringWithKey(“连接”))
    .Mappings(m=>m.FluentMappings.AddFromAssemblyOf())
    .BuildSessionFactory();
    }
    返回工厂;
    }
    }
    //使用CreateQuey获取数据
    使用(IStatelessSession session=SessionManager.SessionFactory.OpenStatelessSession())
    {
    IList lstEmployee=session.CreateCriteria().List();
    return.ToList();
    }
    //使用createquery获取数据
    使用(IStatelessSession session=SessionManager.SessionFactory.OpenStatelessSession())
    {
    IList lstEmployee=session.CreateQuery(“来自员工”).List();
    return.ToList();
    }
    //使用ADO.net获取数据
    DataTable dtEmployees=/*数据使用SQL查询*从ADO.net获取;
    List lstEmployee=新列表();
    foreach(dtEmployees.AsEnumerable()中的DataRow dr)
    {
    雇员=新雇员
    {
    ID=dr字段(“ID”),
    名称=博士字段(“名称”),
    DateOfJoin=dr.Field(“DateOfJoin”),
    DateOfBirth=dr.Field(“DateOfBirth”),
    DepartmentID=dr.Field(“DepartmentID”),
    状态=dr字段(“状态”),
    };
    lstmemployee.Add(Employee);
    
    以下内容将完整的75k结果复制到单独的列表中

    IList<Employee> lstEmployee = ...
    return lstEmployees.ToList<Employee>();
    

    您是否考虑了会话工厂的构建?您在上面的陈述中还说NHibernate实际上更快(867毫秒)。您确定您正在测量您认为正在测量的内容吗?您显示的两个查询完全相同(除了字段和表别名),我看不出它们是如何导致SQL探查器中的执行时间出现这种差异的。另外,请说明您使用的是哪个版本的NHibernate。是否确实要在一个查询中获取75000行?此外,您没有显示所测量的确切代码路径。您应该至少运行几次查询。然后重新运行计算最慢和最快的时间并计算平均值。初始化静态值等可能需要很多时间,而且这些只在第一次发生。我们正在使用NHibernate 3.1。很抱歉,我现在修改了计时。
    return lstEmployees;