2011-04-04 61 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

相关问题