C#LINQ - 我可以在这做什么来提高性能?

时间:2013-04-02 06:54:40

标签: c# performance linq

我正在对集合进行一些重要的过滤(这只是一个封装的“datalines”条目列表)。 我需要在3个字段(日期(字符串),路径(字符串)和ConsolidationCode(字符串))上“合并”这些行。

快速提取3个不同的列表。我更担心的是三重奏...... 我会说正常的“完整_DealerCaseSetComplete包含5000个条目。 日期约为5,路线约为100,合并期为350-500。

我写了以下方法。它完全符合我的要求,但计算时间非常慢。 也许你们可以指导我加快代码执行速度。

如果您需要任何其他代码(实际上非​​常简单,请询问。

private void FillDataGridView()
    {
        //
        _LocalGridControl.Invoke(CreateDataGrid);

        //Filter by Date
        List<string> Dates = _DealerCaseSetComplete.Data.Select(rec => rec.DateAdded).Distinct().ToList();

        //Filter by Route
        List<string> Routes = _DealerCaseSetComplete.Data.Select(rec => rec.Route).Distinct().ToList();

        //Filter by Consolidation
        List<string> Consolidations = _DealerCaseSetComplete.Data.Select(rec => rec.DealerConsolidationCode).Distinct().ToList();

        foreach(string d in Dates)
        {
            foreach(string r in Routes)
            {
                foreach(string c in Consolidations)
                {
                    List<DealerCaseLine> Filter = _DealerCaseSetComplete.Data.Where(rec => rec.DateAdded == d &&
                                                                                    rec.Route == r &&
                                                                                    rec.DealerConsolidationCode == c).ToList();
                    if(Filter.Count > 0)
                        _LocalGridControl.Invoke(AddLineToDataGrid, Filter);
                }
            }
        }
        _LocalGridControl.Invoke(SortDataGrid);
    }

2 个答案:

答案 0 :(得分:2)

看起来您需要按三个字段进行分组:

var filters = from r in _DealerCaseSetComplete.Data
              group r by new { 
                   r.DateAdded, 
                   r.Route, 
                   r.DealerConsolidationCode 
              } into g              
              select g.ToList();

foreach(List<DealerCaseLine> filter in filters)
    _LocalGridControl.Invoke(AddLineToDataGrid, filter);

您的代码会迭代所有数据三次以获取不同的字段。然后它迭代所有数据的,用于所有不同字段的组合(当您使用where子句进行过滤时)。通过这三个字段进行分组,您将仅一次迭代数据。每个结果组至少有一个项目,因此在调用过滤器之前,您无需检查组中是否有任何项目。

答案 1 :(得分:0)

看起来你正试图获得Dates,Routes和Consolidations的每个独特组合。

您当前的代码很慢,因为我认为它是O(n ^ 4)。你有三个嵌套循环,其主体是一个线性搜索。

使用带有IEqualityComparer<T>的Distinct重载可以获得更好的性能:

http://msdn.microsoft.com/en-us/library/bb338049.aspx

var Consolidated = 
  _DealerCaseSetComplete.Data.Select(rec => rec).
  Distinct(new DealerCaseComparer());

DealerCaseComparer的实现方式与上述MSDN链接相同。