Вложенный цикл foreach медленный - PullRequest
1 голос
/ 06 октября 2011

Следующий фрагмент кода достигает желаемых результатов, но производительность очень низкая:

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 коллекции и связывает атрибуты внешних циклов с внутренними.Любые предложения о том, как я могу оптимизировать производительность?

Ответы [ 3 ]

6 голосов
/ 06 октября 2011

Было бы быстрее, если бы вы сначала извлекли все значения 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, обращающемуся к базе данных, вам следует рассмотреть возможность выполнения всех сопоставлений в базе данных, используя вместо этого соединение.

0 голосов
/ 06 октября 2011

Используйте выражения Lamda:

Ниже приведен пример, вы можете оптимизировать это на другой уровень.

    List<SearchResult> allResultGroups=new  List<SearchResult>();
    foreach (SearchResult absaUser in absaUsers)
    {
    resultGroups = srcUsers.Where(g => g.cn == absaUser.absaUID && absaUser.absaEmployeeNumber==g.userID ).ToList();
    }
0 голосов
/ 06 октября 2011

вы можете использовать LINQ join, некоторые примеры: здесь , я предполагаю, что тот, кто встроил его в .NET, нашел довольно оптимальный способ сделать это, а затем повторить цикл.на sidenote: какие у вас типы коллекций?пожалуйста, добавьте их объявление во фрагмент кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...