2010-05-13 75 views
0

我已经写了下面的测试来比较Linq2SQL和NHibernate的性能,我发现结果有点奇怪。映射非常简单,两者完全相同。两者都针对现场数据库运行。虽然我并未删除Linq的广告系列,但这不会影响性能超过10毫秒。Linq2SQL vs NHibernate的性能(我疯了吗?)

的Linq:

[Test] 
    public void Test1000ReadsWritesToAgentStateLinqPrecompiled() 
    { 
     Stopwatch sw = new Stopwatch(); 
     Stopwatch swIn = new Stopwatch(); 
     sw.Start(); 
     for (int i = 0; i < 1000; i++) 
     { 
      swIn.Reset(); 
      swIn.Start(); 
      ReadWriteAndDeleteAgentStateWithLinqPrecompiled(); 
      swIn.Stop(); 
      Console.WriteLine("Run ReadWriteAndDeleteAgentState: " + swIn.ElapsedMilliseconds + " ms"); 
     } 

     sw.Stop(); 
     Console.WriteLine("Total Time: " + sw.ElapsedMilliseconds + " ms"); 
     Console.WriteLine("Average time to execute queries: " + sw.ElapsedMilliseconds/1000 + " ms"); 
    } 

    private static readonly Func<AgentDesktop3DataContext, int, EntityModel.CampaignDetail> 
     GetCampaignById = 
      CompiledQuery.Compile<AgentDesktop3DataContext, int, EntityModel.CampaignDetail>(
       (ctx, sessionId) => (from cd in ctx.CampaignDetails 
            join a in ctx.AgentCampaigns on cd.CampaignDetailId equals a.CampaignDetailId 
            where a.AgentStateId == sessionId 
            select cd).FirstOrDefault()); 

    private void ReadWriteAndDeleteAgentStateWithLinqPrecompiled() 
    { 
     int id = 0; 
     using (var ctx = new AgentDesktop3DataContext()) 
     { 
      EntityModel.AgentState agentState = new EntityModel.AgentState(); 
      var campaign = new EntityModel.CampaignDetail { CampaignName = "Test" }; 
      var campaignDisposition = new EntityModel.CampaignDisposition { Code = "123" }; 
      campaignDisposition.Description = "abc"; 
      campaign.CampaignDispositions.Add(campaignDisposition); 
      agentState.CallState = 3; 

      campaign.AgentCampaigns.Add(new AgentCampaign 
      { 
       AgentState = agentState 
      }); 
      ctx.CampaignDetails.InsertOnSubmit(campaign); 
      ctx.AgentStates.InsertOnSubmit(agentState); 
      ctx.SubmitChanges(); 
      id = agentState.AgentStateId; 
     } 

     using (var ctx = new AgentDesktop3DataContext()) 
     { 
      var dbAgentState = ctx.GetAgentStateById(id); 
      Assert.IsNotNull(dbAgentState); 
      Assert.AreEqual(dbAgentState.CallState, 3); 
      var campaignDetails = GetCampaignById(ctx, id); 

      Assert.AreEqual(campaignDetails.CampaignDispositions[0].Description, "abc"); 
     } 

     using (var ctx = new AgentDesktop3DataContext()) 
     { 
      ctx.DeleteSessionById(id); 
     } 
    } 

NHibernate的(环是一样的):

private void ReadWriteAndDeleteAgentState() 
    { 
      var id = WriteAgentState().Id; 
      StartNewTransaction(); 

      var dbAgentState = agentStateRepository.Get(id); 

      Assert.IsNotNull(dbAgentState); 
      Assert.AreEqual(dbAgentState.CallState, 3); 
      Assert.AreEqual(dbAgentState.Campaigns[0].Dispositions[0].Description, "abc"); 

      var campaignId = dbAgentState.Campaigns[0].Id; 
      agentStateRepository.Delete(dbAgentState); 

      NHibernateSession.Current.Transaction.Commit(); 

      Cleanup(campaignId); 

      NHibernateSession.Current.BeginTransaction(); 
    } 

结果:

NHibernate: 
Total Time: 9469 ms 
Average time to execute 13 queries: 9 ms 

Linq: 
Total Time: 127200 ms 
Average time to execute 13 queries: 127 ms 

LINQ的13.5倍丢了!具有预编译查询的事件(这两个读取查询都是预编译的)。

这不可能是正确的,但我期望NHibernate更快,这只是太大的差异,考虑映射是相同的,NHibernate实际上对数据库执行更多的查询。

更新。我重构了一个项目来使用NHibernate而不是Linq2Sql,并且与在相同映射上进行测试相比,性能增益似乎要低很多(大约20-30%)。有没有人有他们自己的真实世界的例子?

+0

你为什么感到惊讶?认识ORM(或自己写)的人通常认为LING(和EF)并不完全是“此行的顶级产品”;)3级尝试。也许;) – TomTom 2010-05-13 07:07:42

回答

1

在.NET代码和SQL Server数据库上运行一个分析器。另外,还要确定在两种情况下的封面下运行的SQL语句。 LinqToSql的时间在哪里?如果底层的SQL语句不同,为什么?很可能你可以调整两个ORM来加快速度。对于简单的测试,他们可能应该具有相同的球场表现。这感觉就像一个配置问题。

+0

对于一件事,你不能预编译linq中插入,更新和删除的查询,而在NH中,它们在映射过程中生成一次。我不确定实际的SQL,这应该不重要,因为DB是空的,但Linq在QueryBuilders中失去了大部分时间。 – 2010-05-13 10:13:41