2010-05-13 60 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