通过降低算法的复杂性或优化 .NET Core 工具来提高算法的性能

问题描述 投票:0回答:0

我有一个

Outcomes
的列表,我正在加载到内存中;这个列表有一个名为
OutcomeConditions
的属性,它是每个结果的另一个条件列表。我还有一个列表
Rules
,其中包含我从数据源加载到内存中的任意规则。 我的算法只过滤条件至少匹配
Rules
列表中的一个规则的结果。

使用 C# 在 .NET Core 中实现的算法是功能性的,但它是计算密集型的,因此速度很慢。结果数的上限始终为 60(称为 n),规则数的上限为 12(称为 m),对于结果条件,它最多为 3(称为 p);因此复杂度总计为 O(nmp)。

有关重要性的一些上下文:该算法是在 Web API 端点中实现的,该端点非常关键,因为它被频繁调用并在很大程度上影响用户体验。

我使用 EF Core 作为我的 ORM,我尝试了以下方法来提高这个 API 端点和底层服务的整体性能:

  • 为数据访问层实施存储库模式,以
    IQueryable<T>
  • 访问所有数据
  • 使用
    .AsNoTracking()
    从数据库读取只读数据,以减少不必要的跟踪开销
  • 在存储库层尽可能使用批量插入以提高性能,
  • 将所有数据访问和业务逻辑实现为异步处理
  • 实施
    for
    而不是
    foreach
    LINQ
    迭代以减少开销(因为迭代数组比在列表上迭代更快)

这种改进方法是针对所用工具的机械同情,并不令人满意,因为我觉得底层算法可以改进。

这里有一些代码,特别是迭代,从外循环开始:

for (int outcomeIndex = 0; outcomeIndex < inputOdds.Length-1; outcomeIndex++)
{
     var savedOutcome = await oddService.GetOutcomeByOutcomeId(inputOdds[outcomeIndex].OutcomeId);
     var filteredOutcome = await conditionService.FilterOutcomeConditions(savedOutcome, umbracoGame,language, IsFilterActive);

     if (filteredOutcome != null && !IsDuplicateOutcome(filteredOutcome, filteredOdds))
         filteredOdds.Add(await CustomizeUmbracoOutcome(filteredOutcome));
}

外部循环遍历每个结果并调用

FilterOutcomeConditions
方法,其中一部分如下所示(并包含一个嵌套循环,用于根据规则列表验证每个结果条件):

foreach (var rule in umbracoGame.OutcomeRules)
            {
                var validConditions = new List<OutcomeCondition>();
                if (filterActive && !rule.IsActive)
                    continue;
                foreach (var condition in outcomeConditions)
                    ValidateIfConditionMeetsCurrentUmbracoRule(rule, validConditions, condition);

                int numberOfRules = await GetNumberOfUmbracoRulesForOutcome(rule);
                if (validConditions.Count > 0 && outcomeConditions.Count() == numberOfRules)
                    if (doConditionsMeetUmbracoRequirements(validConditions, rule))
                    {
                        filteredOutcome.Conditions = validConditions.Select(x=>mapper.Map<OutcomeCondition, OutcomeConditionDto>(x));
                        filteredOutcome.Summary = rule.Summary;
                        filteredOutcome.Title = rule.Title;
                        filteredOutcome.Thumbnail = rule.Thumbnail;
                        return filteredOutcome;
                    }
            }
            return null;

我想知道是否有一种方法可以优化目前在时间和空间上为 O(nmp) 的核心算法。或者,我可能忽略(或错误解释)的工具(.NET Core、EF Core 等)的任何性能增强将不胜感激。

performance entity-framework-core asp.net-core-webapi query-optimization nested-loops
© www.soinside.com 2019 - 2024. All rights reserved.