2012-07-18 62 views
2

我有一個很大的方法。 其中我有一些C#計算,我也打電話3/4存儲過程。 構建3/4對象並最終添加到列表中並返回列表。如何提高方法的性能

我的目標是提高此方法的性能,以便執行時間更短。

我的問題是,有什麼辦法可以檢查方法的每個部分,並找出哪個部分需要時間來執行? 可能是一些looging或東西!

我正在使用LINQ to EF。

+0

如果你想記錄它,'Stopwatch'類可能是你感興趣的。另外,如果有一點你認爲可能是一個問題,那麼有人可能會發現它運行緩慢的原因。 – KingCronus 2012-07-18 20:06:36

+1

您總是可以分別對每段代碼進行計時,但這看起來像是使用樣本分析的一個很好的情況。 – Thomas 2012-07-18 20:06:43

+0

爲什麼不在http://codereview.stackexchange.com/上獲取您的代碼 – HatSoft 2012-07-18 20:07:55

回答

3

投資性能分析器,如Ants from Redgate。一些更好的Visual Studio版本也附帶了一個。

至少,你可以嘗試使用System.Diagnostics.Stopwatch

從MSDN:

static void Main(string[] args) 
{ 
    Stopwatch stopWatch = new Stopwatch(); 
    stopWatch.Start(); 
    Thread.Sleep(10000); 
    stopWatch.Stop(); 
    TimeSpan ts = stopWatch.Elapsed; 

    string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", 
     ts.Hours, ts.Minutes, ts.Seconds, 
     ts.Milliseconds/10); 

    Console.WriteLine("RunTime " + elapsedTime); 
} 
+0

如果您認爲某件事比預想的要慢,則秒錶是您的第一個選擇。 – 2012-07-18 20:19:49

1

什麼你要找的是一個分析器 - 探查器中運行你的程序,並告訴你有多少時間每行的代碼需要執行,以及執行時間佔總執行時間的百分比。

一個很棒的C#探查器是ANTS .Net Profiler,它相當昂貴,但它有14天的免費試用 - 我認爲這對你的需求是完美的。

1

你有幾個選擇。我發現自己使用停止手錶來測試這種事情。在你做任何事之前,你必須確保代碼已經不夠好。如果沒有損壞,不要修復它往往是最好的建議。如果你仍然感興趣,你可以做這樣的事情:

Stopwatch sw = Stopwatch.StartNew(); 

// do some code stuff here 

sw.Stop(); 

Console.WriteLine(sw.ElapsedTicks); 

你也有秒,毫秒和其他測量在sw變量。

+0

謝謝。我會嘗試。這是一個wcf,客戶端是iPhone。它在3秒內返回數據,但要求更快。 – kandroid 2012-07-18 20:33:25

1

我的建議是你用JetBrains dottrace它有一定的指向熱點,告訴你哪個一段代碼已經採取多久

PS非常有益的功能:它救了我的脖子幾次

0

數據庫訪問通常比您可能做出的任何計算都慢幾個數量級(除非您正在嘗試預測未來天氣)。因此,LINQ-to-EF部分很可能在時間流逝的地方丟失。

您可以使用分析器來分析程序。 SQL-Server有一個分析器,允許您監視查詢。如果你想分析代碼,谷歌的.NET分析器,你會發現不少有一個免費的許可證。或者購買一個,如果你覺得它有用。 EQATEC profiler對我來說非常有用。

如果你有一個很大的方法,你的代碼結構嚴重不足。制定一個大方法不會比將其分解成更小的邏輯部分更快。較小的部分將更容易維護,並且代碼分析器將產生更多有用的信息,因爲它們通常只返回方法調用總數,並且不顯示單行代碼的時間。

3

如果可能,您可以嘗試並行執行存儲過程。我已經看到這種性能提高了很多,特別是如果您的存儲過程只是讀取而沒有寫入。

它可能是這個樣子:

ConcurrentBag<Result> results = new ConcurrentBag<Result>(); 

Parallel.Invoke(
       () => { 
        var db = new DatabaseEntities(); 
        Result result1 = db.StoredProcudure1(); 
        results.Add(result1); 
       } 
       () => { 
        var db = new DatabaseEntities(); 
        Result result2 = db.StoredProcudure2(); 
        results.Add(result2); 
       } 
       () => { 
        var db = new DatabaseEntities(); 
        Result result3 = db.StoredProcudure3(); 
        results.Add(result3); 
       } 
); 

return results; 

我使用的是ConcurrentBag這裏,而不是一個List的,因爲它是線程安全的。

+0

不錯!真的很喜歡這個! +1 – 2012-07-18 21:09:27