diff --git a/ArchUnitNET/Fluent/ConditionManager.cs b/ArchUnitNET/Fluent/ConditionManager.cs index 3c05cf368..2cee964e1 100644 --- a/ArchUnitNET/Fluent/ConditionManager.cs +++ b/ArchUnitNET/Fluent/ConditionManager.cs @@ -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; @@ -98,17 +97,41 @@ public IEnumerable EvaluateConditions(IEnumerable 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 FindResultsForObject(List> conditionResults, T canBeAnalyzed) + { + return conditionResults.Select(results => results[canBeAnalyzed]); + } + + private static IEnumerable FindResultsForObject(List> conditionResults, T t) + { + return conditionResults.Select(results => results.Find(x => x.ConditionResult.AnalyzedObject.Equals(t))); + } + private static EvaluationResult CreateEvaluationResult( IEnumerable conditionElementResults, Architecture architecture, ICanBeEvaluated archRuleCreator) @@ -298,7 +321,7 @@ public override int GetHashCode() } } } - + private class ConditionElementResult { public readonly ConditionResult ConditionResult; @@ -311,4 +334,6 @@ public ConditionElementResult(ConditionResult conditionResult, LogicalConjunctio } } } + + } \ No newline at end of file