Skip to content

Commit 553f1df

Browse files
authored
Merge pull request #167 from gbtb/perf_improvement_in_ConditionManager
Added dictionary as a ordering/search method for large enough evaluation results
2 parents 2ac6487 + 3fb1ccf commit 553f1df

File tree

1 file changed

+33
-8
lines changed

1 file changed

+33
-8
lines changed

ArchUnitNET/Fluent/ConditionManager.cs

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
using ArchUnitNET.Domain.Extensions;
1212
using ArchUnitNET.Fluent.Conditions;
1313
using ArchUnitNET.Fluent.Extensions;
14-
using ArchUnitNET.Fluent.Freeze;
1514
using ArchUnitNET.Fluent.Predicates;
1615
using JetBrains.Annotations;
1716

@@ -98,17 +97,41 @@ public IEnumerable<EvaluationResult> EvaluateConditions(IEnumerable<T> filteredO
9897
yield break;
9998
}
10099

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

104-
foreach (var t in filteredObjectsList)
108+
foreach (var t in filteredObjectsList)
109+
{
110+
yield return CreateEvaluationResult(FindResultsForObject(conditionResults, t), architecture, archRuleCreator);
111+
}
112+
}
113+
else
105114
{
106-
yield return CreateEvaluationResult(
107-
conditionResults.Select(results => results.Find(x => x.ConditionResult.AnalyzedObject.Equals(t))),
108-
architecture, archRuleCreator);
115+
var conditionResults = _conditionElements.Select(conditionElement =>
116+
conditionElement.Check(filteredObjectsList, architecture).ToList()).ToList();
117+
118+
foreach (var t in filteredObjectsList)
119+
{
120+
yield return CreateEvaluationResult(FindResultsForObject(conditionResults, t), architecture, archRuleCreator);
121+
}
109122
}
110123
}
111124

125+
private IEnumerable<ConditionElementResult> FindResultsForObject(List<Dictionary<ICanBeAnalyzed, ConditionElementResult>> conditionResults, T canBeAnalyzed)
126+
{
127+
return conditionResults.Select(results => results[canBeAnalyzed]);
128+
}
129+
130+
private static IEnumerable<ConditionElementResult> FindResultsForObject(List<List<ConditionElementResult>> conditionResults, T t)
131+
{
132+
return conditionResults.Select(results => results.Find(x => x.ConditionResult.AnalyzedObject.Equals(t)));
133+
}
134+
112135
private static EvaluationResult CreateEvaluationResult(
113136
IEnumerable<ConditionElementResult> conditionElementResults,
114137
Architecture architecture, ICanBeEvaluated archRuleCreator)
@@ -298,7 +321,7 @@ public override int GetHashCode()
298321
}
299322
}
300323
}
301-
324+
302325
private class ConditionElementResult
303326
{
304327
public readonly ConditionResult ConditionResult;
@@ -311,4 +334,6 @@ public ConditionElementResult(ConditionResult conditionResult, LogicalConjunctio
311334
}
312335
}
313336
}
337+
338+
314339
}

0 commit comments

Comments
 (0)