Skip to content

Commit

Permalink
Merge pull request #167 from gbtb/perf_improvement_in_ConditionManager
Browse files Browse the repository at this point in the history
Added dictionary as a ordering/search method for large enough evaluation results
  • Loading branch information
fgather authored Aug 7, 2022
2 parents 2ac6487 + 3fb1ccf commit 553f1df
Showing 1 changed file with 33 additions and 8 deletions.
41 changes: 33 additions & 8 deletions ArchUnitNET/Fluent/ConditionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
using ArchUnitNET.Domain.Extensions;
using ArchUnitNET.Fluent.Conditions;
using ArchUnitNET.Fluent.Extensions;
using ArchUnitNET.Fluent.Freeze;
using ArchUnitNET.Fluent.Predicates;
using JetBrains.Annotations;

Expand Down Expand Up @@ -98,17 +97,41 @@ public IEnumerable<EvaluationResult> EvaluateConditions(IEnumerable<T> filteredO
yield break;
}

var conditionResults = _conditionElements.Select(conditionElement =>
conditionElement.Check(filteredObjectsList, architecture).ToList()).ToList();
//rough heuristic - if we have small number of comparisons, we are fine with sequential search
//but in large cases its quadratic behavior becomes too slow and building of a dictionary is justified
if (filteredObjectsList.Count * _conditionElements.Count > 256)
{
var conditionResults = _conditionElements.Select(conditionElement =>
conditionElement.Check(filteredObjectsList, architecture).ToDictionary(x => x.ConditionResult.AnalyzedObject))
.ToList();

foreach (var t in filteredObjectsList)
foreach (var t in filteredObjectsList)
{
yield return CreateEvaluationResult(FindResultsForObject(conditionResults, t), architecture, archRuleCreator);
}
}
else
{
yield return CreateEvaluationResult(
conditionResults.Select(results => results.Find(x => x.ConditionResult.AnalyzedObject.Equals(t))),
architecture, archRuleCreator);
var conditionResults = _conditionElements.Select(conditionElement =>
conditionElement.Check(filteredObjectsList, architecture).ToList()).ToList();

foreach (var t in filteredObjectsList)
{
yield return CreateEvaluationResult(FindResultsForObject(conditionResults, t), architecture, archRuleCreator);
}
}
}

private IEnumerable<ConditionElementResult> FindResultsForObject(List<Dictionary<ICanBeAnalyzed, ConditionElementResult>> conditionResults, T canBeAnalyzed)
{
return conditionResults.Select(results => results[canBeAnalyzed]);
}

private static IEnumerable<ConditionElementResult> FindResultsForObject(List<List<ConditionElementResult>> conditionResults, T t)
{
return conditionResults.Select(results => results.Find(x => x.ConditionResult.AnalyzedObject.Equals(t)));
}

private static EvaluationResult CreateEvaluationResult(
IEnumerable<ConditionElementResult> conditionElementResults,
Architecture architecture, ICanBeEvaluated archRuleCreator)
Expand Down Expand Up @@ -298,7 +321,7 @@ public override int GetHashCode()
}
}
}

private class ConditionElementResult
{
public readonly ConditionResult ConditionResult;
Expand All @@ -311,4 +334,6 @@ public ConditionElementResult(ConditionResult conditionResult, LogicalConjunctio
}
}
}


}

0 comments on commit 553f1df

Please sign in to comment.