C # Оптимизированный алгоритм слияния - PullRequest
0 голосов
/ 20 сентября 2018

У меня есть служба извлечения данных, через которую мое приложение C # извлекает данные.Данные извлекаются с использованием нескольких заданий, и после завершения запроса данных служба извлечения данных вызывает метод notify, который я реализовал в своем классе приложения.

Ниже приведен код метода notify.Он просто проверяет, являются ли результаты не пустыми, а затем вызывает mergeResults в новом потоке.

public override void notify(List<IFields> results)
{
     if (!results.IsNullOrEmpty())
     {
         Task.Run(() => { mergeResults(results); });
     }
}

Я использую Список для хранения окончательных результатов слияния.

List<IFields> mergedResults;

Я использую object mergeLock для взаимного исключения.

Вот логика слияния, которую я использую:

    public void mergeResults(List<IFieldsByPrePost> results)
    {
        lock (mergeLock)
        {
            foreach (var result in results)
            {
                if (mergedResults.Count > 0)
                {
                    var properties = mergedResults.First().getDiffProperties();
                    bool isMatch = false;
                    foreach (var mergedResult in mergedResults)
                    {
                        isMatch = true;
                        foreach (var property in properties)
                        {
                            var value1 = mergedResult.GetType().GetProperty(property).GetValue(mergedResult).ToString();
                            var value2 = result.GetType().GetProperty(property).GetValue(result).ToString();
                            if (value1 != value2) { isMatch = false; break; }
                        }
                        if (isMatch)
                        {
                            mergedResult.Count += result.Count;
                            break;
                        }
                    }
                    if (!isMatch)
                    {
                        mergedResults.Add(result);
                    }
                }
                else
                {
                    mergedResults.Add(result);
                }
            }
        }
    }

Вышеприведенная логика работает, но она оченьмедленно, когда в метод передается большой набор результатов.

Кроме того, метод извлечения данных несколько раз вызывается службой извлечения данных с различными наборами результатов, что еще больше замедляет его.

Я ищу лучший подход для решения этой проблемы.

TLDR;Этот алгоритм медленный, кто-нибудь может показать мне способ заставить его работать быстрее?

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Первое, что бросается в глаза, это то, что метод mergeResults не является универсальным, поэтому я не уверен, зачем нужно размышление.Удаление строк:

var value1 = mergedResult.GetType().GetProperty(property).GetValue(mergedResult).ToString();
var value2 = result.GetType().GetProperty(property).GetValue(result).ToString();
if (value1 != value2) { isMatch = false; break; }

и использование прямого свойства:

if(mergedResult.Property1 == result.Property1) { isMatch = false; break; }

может помочь.

0 голосов
/ 20 сентября 2018

Я бы предположил, что IFields и / или IFieldsByPrePost являются производными от

IEquatable<IFields> and/or IEquatable<IFieldsByPrePost>. 

Так что вы можете просто проверить равенство с

IFields fields1;
IFieldsByPrePost fields2;
bool equal = fields1.Equals(fields2);

Таким образом, вы обойдете Reflection, которыйзамедляет ваш кодТогда это просто

foreach (var result in results)
{
  if (!mergedResults.Any(x => x.Equals(result))
  {
    mergedResults.Add(result);
  }
}

Я не знаю, что вы делаете с

mergedResult.Count,

, поэтому я опускаю это.

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