2011-05-31 106 views
0

更新:Andrew和Conrad的答案同樣有幫助。時間問題的簡單修復解決了問題,並緩存了更大的對象引用,而不是每次移除問題源時重新構建它們。感謝您的意見,夥計們。.net部分運行緩慢

我正在使用c#.NET API,出於某種原因,下面的代碼會執行我感覺非常/非常慢的操作。

這是一個System.Timers.Timer的處理程序,它每5秒觸發一次它發生的事件。

private static void TimerGo(object source, System.Timers.ElapsedEventArgs e) 
    { 
     tagList = reader.GetData(); // This is a collection of 10 objects. 

     storeData(tagList); // This calls the 'storeData' method below 

    } 

而且storeData方法:

private static void storeData(List<obj> tagList) 
    { 
     TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1)); 
     long timestamp = (long)t.TotalSeconds; 

     foreach (type object in tagList) 
     { 
      string file = @"path\to\file" + object.name + ".rrd"; 

      RRD dbase = RRD.load(file); 

      // Update rrd with current time timestamp and data. 
      dbase.update(timestamp, new object[1] { tag.data }); 
     } 
    } 

我失去了一些明顯的資源池?您看到的RRD內容來自rrdtool的NHawk C#封裝器;在這種情況下,我用它更新了10個不同的文件,但我沒有看到爲什麼它需要這麼長時間。當我說「這麼久」,我的意思是計時器在第一次更新完成之前第二次觸發,所以最終「更新2」會在「更新1」之前發生,因爲「更新1」具有早於「更新2」的時間戳。

我將計時器長度增加到10秒,並且運行時間更長,但仍然最終超出本身並嘗試使用較早的時間戳更新文件。我可以採取什麼不同的做法來提高效率,因爲很明顯,我正在做一些大大的錯誤...

+2

您是否嘗試過分析rrd命令? – Alxandr 2011-05-31 21:08:26

+0

甚至可以剖析讀者......從這段代碼中無法分辨出實際問題。分析整個事情以確定時間花在哪裏。此外,您還想知道文件系統在其他方面的負載情況。 – NotMe 2011-05-31 21:20:52

回答

1

您的tagList中的每個標籤是否存在不同的RRD文件?在你的僞代碼中,你打開每個文件N次。 (你指出列表中只有10個對象被認爲是)。然後你執行更新。我只能假設你在更新完RRD文件後才處理它。如果你不保存對一個打開文件的引用。

如果RRD是相同的,但您只是將不同類型的繪圖數據放入單個文件中,那麼只要您希望對其進行專有寫入訪問,就只需保持其打開狀態即可。

沒有譜,你有幾個選項的代碼(我推薦分析BTW)

保持RRD文件打開

緩存打開的文件,以防止您不必打開,寫密切每5每個文件的秒數。只需緩存10個打開的文件引用並每5秒寫入一次。

獨立從數據寫入

看樣子你是從一些對象採取的度量樣本每5秒的數據收集。如果你沒有對文件進行「拖尾」處理,請將文章分開。把你的數據樣本放入一個隊列中進行處理。處理器將使每個tagList出列並儘可能快地寫入,從隊列中返回更多列表。

通過這種方式,即使寫入機制變慢​​,您也可以確保獲得約5秒的樣本。

+0

是的,tagList中的每個元素都有一個單獨的文件,編輯上述內容以反映這一點。使用NHawk庫可以防止我對實際的文件處理有任何控制 - 據我所知,它只是一個方便的接口,用於執行一個進程。rrd可執行文件的開始(),然後處理所有的文件IO。 – uscere90 2011-05-31 21:34:23

+0

@ uscere90那麼最好的辦法是將數據收集與數據寫入分開。如果您需要詳細說明,我會更新我的答案。 – 2011-05-31 21:40:39

+0

如果你不介意詳細說明,那會很棒。我現在正在與一名探查者一起玩,看看我是否可以縮小它瓶頸處的位置,但是設置一個排隊系統以促進一致的寫作似乎是一個很好的第二選擇。 – uscere90 2011-05-31 22:01:49

1

使用探查器。 JetBrains是我個人的建議。使用程序運行分析器,並查找花費最長時間運行的線程/方法。這聽起來非常像IO或數據問題,但從示例代碼中看不出來。

2

並不真正回答你的perf問題,但是如果你想修復rentrancy位,你的timer.AutoRest設置爲false,然後在方法結尾調用start()。

private static void TimerGo(object source, System.Timers.ElapsedEventArgs e) 
{ 
    tagList = reader.GetData(); // This is a collection of 10 objects. 

    storeData(tagList); // This calls the 'storeData' method below 
    timer.Start(); 
}