ArchUnitNET icon indicating copy to clipboard operation
ArchUnitNET copied to clipboard

AreAssignableTo is extremely slow.

Open wiewiur25 opened this issue 3 years ago • 6 comments

Hello.

I have a problem with performance AreAssignableTo method. Example Code below:

`public class DomainDependenciesTests { private Architecture _architecture; private GivenClassesConjunction _entitiesClasses;

    [OneTimeSetUp]
    public void LoadAssemblies()
    {
        _architecture = new ArchLoader()
            .LoadAssemblies(Assembly.Load("xx.xxx.xxx"))
            .Build();

        _entitiesClasses = Classes().That().AreAssignableTo(typeof(EntityBase));
    }

    [Test]
    public void Entities_CheckAllAssignableToEntityBase_ShouldAllNotContainingDependenciesToRepositoriesAndEventsAndServices()
    {
        var forbiddenTypes = Types().That().AreAssignableTo(typeof(RepositoryBase))
            .Or().ImplementInterface(typeof(IEvent))
            .Or().HaveFullNameContaining("Service");

        // var testEntities = _entitiesClasses.GetObjects(_architecture).ToList(); --> return >400 classes time: a few min. ~3min
        // var testAllowedTypes = forbiddenTypes.GetObjects(_architecture).ToList(); --> return > 1200 types ~5min

        var entitiesOnlyDependOnDomain = _entitiesClasses.Should().NotDependOnAny(forbiddenTypes);
        var result = entitiesOnlyDependOnDomain.Evaluate(_architecture); // --> nevending story more than 10min
        result.Should().AllPassed();
    }
}`

I know it will be hard to reproduce without my project, but maybe you know about some problem of performance in your sides? Or maybe you can see, what I doing wrong. I didn't see perf problem before but I usually used methods based on Namespace.

Thank you in advance. Have a good day!

wiewiur25 avatar Feb 07 '22 12:02 wiewiur25

Any help?

wiewiur25 avatar Mar 14 '22 07:03 wiewiur25

Hi, we had a small test on this on Friday and were not really able to reproduce the issue unfortunately, even on larger code-bases. However, @brandhuf will further look into this. Do you have any idea, what is different with the code base you are scanning is it extremely large?

fgather avatar Mar 14 '22 07:03 fgather

As I described above, _entitiesClasses.GetObjects(_architecture).ToList(); return ~400 classes and forbiddenTypes.GetObjects(_architecture).ToList(); return ~1200 types. It's quite big but IMO not extremely large.

wiewiur25 avatar Mar 14 '22 07:03 wiewiur25

I debug a little bit and I see, the most of time (almost all) are ConditionManager.EvaluateConditions() when filteredObjectsList.ToList(). Result of this conversion are 389 objects, its too big?

Second place wich have a big impact of time is place where arises conditionResults in same method. Maybe this will help?

Additionally I using FluetAssertion and I created custom assertion. Code below: ` public AndConstraint<ArchUnitEvaluationResultAssertions> AllPassed() { var fails = Subject.Where(x => !x.Passed); Execute.Assertion.BecauseOf("", null) .Given(() => fails) .ForCondition(x => !x.Any()) .FailWith(FailMessage(fails.ToList()));

        return new AndConstraint<ArchUnitEvaluationResultAssertions>(this);
    }

    private string FailMessage(IList<EvaluationResult> fails)
    {
        if (!fails.Any())
        {
            return string.Empty;
        }
        var failsMessage = string.Join(",\r\n",fails.Select(x => x.EvaluatedObject));
        var ruleMessage = fails.First().ArchRule.Description;
        return $"Wrong dependecies in types:\r\n{failsMessage} .\r\n {ruleMessage}";
    }`

What I'm doing wrong? Or maybe my solution is too big for yours library?

wiewiur25 avatar Mar 14 '22 10:03 wiewiur25

Hi, the number of classes shouldn't be an issue, same holds true for the number of findings. We use the library in far bigger codebases. We'll try to reproduce the issue, however to be honest the focus for the next two weeks will be on finalizing changes for the upcoming release.

fgathercoupa avatar Mar 24 '22 19:03 fgathercoupa

@wiewiur25 , sorry for catching up that late. Did you try to run the test with newer versions? We snuck some performance fixes inside, which might already have helped.

fgather avatar Jul 24 '22 17:07 fgather

Closing the issue, feel free to reopen it, if the problem still exists.

fgather avatar Sep 27 '22 22:09 fgather