嵌套的foreach循环缓慢

时间:2011-10-06 09:19:30

标签: c# optimization foreach

下面的代码可以获得理想的结果,但性能非常慢:

SearchResultCollection absaUsers = ABSAds.FindAll();
SearchResultCollection srcUsers = ds.FindAll();

foreach (SearchResult users in srcUsers)
{
    string cn = users.Properties["cn"][0].ToString();
    string sn = users.Properties["sn"][0].ToString();
    string userID = users.Properties["uid"][0].ToString();
    string description = users.Properties["PersonnelAreaDesc"][0].ToString();
    string jobCodeID = users.Properties["JobcodeID"][0].ToString();
    string CostCentreID = users.Properties["costCentreID"][0].ToString();
    string CostCentreDescription = users.Properties["CostCentreDescription"][0].ToString();
    string givenName = users.Properties["givenName"][0].ToString();
    string employmentStatus = users.Properties["EmploymentStatus"][0].ToString();
    string EmploymentStatusDescription = users.Properties["EmploymentStatusDescription"][0].ToString();

    foreach (SearchResult absaUser in absaUsers)
    {

        string absaUID = absaUser.Properties["uid"][0].ToString();
        string absaEmploymentStatus = absaUser.Properties["EmploymentStatus"][0].ToString();
        string absaEmploymentStatusDescription = absaUser.Properties["EmploymentStatusDescription"][0].ToString();
        string absaEmployeeNumber = absaUser.Properties["employeeNumber"][0].ToString();

        if (absaUID == cn && absaEmployeeNumber==userID)
        {
            Console.WriteLine("User Record Found:" + cn);
            sw.WriteLine("Modify" + "," + cn + "," + description + "," + userID + "," + givenName + "," + sn + "," + jobCodeID + "," + CostCentreID + "," + CostCentreDescription + "," + sn + "," + cn + "," + employmentStatus + "," + EmploymentStatusDescription);
            sw.Flush();
            break;
        }
    }
}

它遍历2个集合,并使用内部的mtaches外部循环属性。关于如何优化性能的任何建议?

3 个答案:

答案 0 :(得分:6)

如果首先将所有absaUID值提取到查找中,那么会更快:

var lookup = absaUsers.Cast<SearchResult>()
                      .ToLookup(x => x.Properties["uid"][0].ToString());

然后你可以使用:

foreach (SearchResult users in srcUsers)
{
    string cn = users.Properties["cn"][0].ToString();
    foreach (SearchResult matches in lookup[cn])
    {
        ...
    }
}

你还没有展示如何定义absaUsers - 如果它是一个LINQ查询表达式,那么你现有的代码可能会在每次迭代时进入数据库 - 而上面的胜利'吨。另一方面,如果srcUsers 也是与数据库通信的LINQ查询表达式,则应考虑使用连接在数据库中进行所有匹配。

答案 1 :(得分:0)

你可以使用LINQ连接,一些例子是here,我假设无论是谁将它构建到.NET中都找到了一种非常理想的方法,然后循环使用它。旁注:你的收藏类型是什么?请将他们的声明添加到代码段。

答案 2 :(得分:0)

使用Lambda表达式:

下面是示例1,您可以将其优化到另一个级别。

    List<SearchResult> allResultGroups=new  List<SearchResult>();
    foreach (SearchResult absaUser in absaUsers)
    {
    resultGroups = srcUsers.Where(g => g.cn == absaUser.absaUID && absaUser.absaEmployeeNumber==g.userID ).ToList();
    }