2011-04-04 60 views
3

好了,可以說我有類如下列:C#泛型的效率,更好的方法來做到這一點

public class KPIObject<T> //<--This class where T is the following classes 
{ 
    public List<T> Data { get; set; } 
    public string Caption { get; set; } 
} 

public class KPICycleCountAccuracyData //<--There are 20 of these with different names and values 
{ 
    public string Facility { get; set; } 
    public string CCAdjustedCases { get; set; } 
    public string TotalCases { get; set; } 
    public string CCAdjustedPercent { get; set; } 
} 

然後,我有:

public List<ReportData>> ProcessAccountReport(GetAccountReport request) 
{ 
    var data = new List<ReportData>(); 
    ProcessKPI(data, request.KPICycleCountAccuracy, "KPICycleCountAccuracy"); //<-- 20 of these 
    return data; 
} 

這裏是ProcessKPI方法:

private static void ProcessKPI<T>(List<ReportData> data, ICollection<KPIObject<T>> items, string name) 
{ 
    if (items == null || items.Count <= 0) return; 
    foreach (var item in items) 
    { 
     if (item.Data == null || item.Data.Count <= 0) continue; 
     var temp = new List<object>(); 
     temp.AddRange((IEnumerable<object>)item.Data); 
     data.Add(new ReportData { Data = temp, Name = name, Title = item.Caption }); 
    } 
} 

所有這些工作和編譯正確,我只是想知道這是否是這樣做的最有效的方式。

謝謝。

編輯

我改變過程KPI這樣:

private static void ProcessKPI<T>(ICollection<ReportData> data, ICollection<KPIObject<T>> items, string name) 
     { 
      if (items == null || items.Count <= 0) return; 
      foreach (var item in items.Where(item => item.Data != null && item.Data.Count > 0)) 
      { 
       data.Add(new ReportData { Data = (IEnumerable<object>)item.Data, Name = name, Title = item.Caption }); 
      } 
     } 
+0

只是要清楚你正在尋找什麼類型的效率增益:你是否說你正在對ProcessKPI()進行20次調用(對於你在第一個代碼片斷中指出的20種類型中的每一種都有一個調用),如果你添加了一個類型,你將不得不再增加一個調用到'ProcessKPI()'等等。你正在尋找一種更具擴展性的方式來編寫這段代碼? – 2011-04-04 19:56:14

+0

性能,更少的代碼,內存問題。是的,如果我添加另一個班級,我必須再次進行ProcessKPI調用。 – Cyberdrew 2011-04-04 19:57:51

+1

不知道它的長度,但我知道你的數據參數不需要是ref,因爲它不是一個值類型。 – 2011-04-04 19:58:46

回答

1

意見夫婦

  • 沒有必要做一個data參數refProcessKPI。如果實際分配給它,則參數ref僅對C#中的class類型有意義。在這裏,你只是修改對象,所以ref不是由你任何東西,除了尷尬的呼叫語法
  • 即使Count簽名它永遠不會返回一個負值。
  • 我比as IEnumerable<object>版本更喜歡(IEnumerable<object>)item.Data。如果後者失敗,則會導致ArgumentNullException,當它真的是一個鑄造問題。
+0

我刪除了ref並更改了IEnumerable的位置。謝謝。 – Cyberdrew 2011-04-04 20:02:49

1

速度 假設你正在談論的計算效率(即速度),有兩個操作,你可能能夠改善:

首先,創建item.Datatemp副本變量。當您知道生成的ReportData將永遠不會被修改時,您可以直接使用item.Data,放棄昂貴的複製操作。

data.Add(new ReportData { Data = (IEnumerable<object>)item.Data, Name = name, Title = item.Caption });

二,轉換爲IEnumerable<object>可能會造成不必要的拳擊/在以後拆箱。查看您的應用程序是否有意向ReportData添加通用類型參數,以便將其實例化爲new ReportData<KPIObject>()。這樣編譯器可以更好地優化代碼。

內存 使用延續你可以在同一時間,而不是一下子就處理一個ReportData元素,從而減少內存佔用量實現您的解決方案。看看yield聲明,看看如何推動這種方法。

其他 爲了進一步提高代碼質量,JaredPar的答案提供了一些極好的建議。

+0

很棒的建議。 – Cyberdrew 2011-04-04 20:25:57

+1

我認爲你錯了,我沒有看到任何複製這種方法。列表操作都是引用,字符串副本都是引用。所以他最多隻能複製一些指針地址。另外我相信你的拳擊陳述是不合理的,除非OP正在處理名單等,當類型是參考類型時沒有出現拳擊。 -1爲此,+1爲收益率信息 – 2011-04-04 20:29:06

+1

@ChrisMarisic AddRange()確實複製了所有引用,而不是完整的對象。我並不是想暗示所有字符串都被複制。但是仍然需要在每次迭代中複製20個引用;根據列表的實施情況,可能生活在不連續的記憶中。它的成本可能很小,但是放棄AddRange()的複製操作肯定比放置它快。 – 2011-04-04 20:41:59

相關問題