2012-07-26 87 views
0

今天早上我寫了一個快速客戶端,當我注意到後續保存後,性能會降低,只是將一堆數據插入到表存儲中。爲什麼性能會隨着對TableServiceContext.SaveChanges的多次調用而降低

public class MyObject : TableServiceEntity 
{ 
    public MyObject() 
    { 
     this.RowKey = Guid.NewGuid().ToString(); 
    } 

    public string SomeProperty { get; set; } 
} 

然後,我有一個簡單的代碼塊添加一些數據....

Stopwatch timer = new Stopwatch(); 
      for (int i = 0; i < target/50; i++) 
      { 
       CloudTableClient client = account.CreateCloudTableClient(); 
       client.CreateTableIfNotExist(entitySet); 
       TableServiceContext context = client.GetDataServiceContext(); 

       timer.Reset(); 
       timer.Start(); 
       for (int x = 0; x < i * 50; x++) 
       { 
        var obj = new MyObject(); 

        context.AddObject(entitySet, obj); 
        context.SaveChanges(); 
       } 
       total += 100; 
       timer.Stop(); 

       Console.WriteLine("Added 100 entities in {0} seconds; total: {1}", timer.Elapsed.Seconds, total); 
      } 

這裏是我所看到的,當它運行(控制檯應用程序)

Added 100 entities in 0 seconds; total: 100 

Added 100 entities in 0 seconds; total: 200 

Added 100 entities in 1 seconds; total: 300 

Added 100 entities in 2 seconds; total: 400 

Added 100 entities in 4 seconds; total: 500 

Added 100 entities in 4 seconds; total: 600 

Added 100 entities in 6 seconds; total: 700 

Added 100 entities in 6 seconds; total: 800 

爲什麼性能下降?

  • 如果我移動背景下,客戶端和/或賬戶圈外
  • 實施context.ResolveType並沒有解決問題
  • 分析之後,在沒有發生變化, context.SaveChanges方法是瓶頸的地方
  • 重新運行該應用程序會重現相同的結果;即使數據庫中有數百/數千個其他實體。

回答

1

我相信你的測試代碼有一個錯誤,在這一行。

for (int x = 0; x < i * 50; x++) 

你迭代高達i * 50倍,因此通過外循環,每次你會比前次增加50多個實體。第一次通過添加0個實體,確實非常快。然後是50,然後是100,然後是150,等等,這是被掩蓋的,因爲你的日誌代碼每次都會盲目地向計數增加100,即使這不是你實際添加的數字。你可能想要的是:

for (int x = 0; x < 100; x++) 

關於分析結果,這段代碼的大部分工作在內存中的數據。 SaveChanges()會進行網絡通話,這就是爲什麼它佔據了花費的時間。

我意識到這是測試代碼。但是,如果您實際上試圖將大量實體添加到單個PartitionKey,建議使用批處理。

+0

謝謝!它驚人的容易忽略它! – 2012-07-26 18:38:08

相關問題