Skip to content

Optimize the implementation of the _MvcCopyDependencyFiles Target in the Mvc.Testing.targetsΒ #63977

@baronfel

Description

@baronfel

Is there an existing issue for this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe the problem.

The _MvcCopyDependencyFiles Target has a few patterns that lead to poor performance during a build. This is especially visible during incremental builds, which are supposed to do work as minimally as possible.

Image

On this binlog snap from an internal build, we can see that this Target calls the Copy Task an astonishing number of times. This leads to a significant amount of overhead, which when coupled with the lack of Input/Output modeling on the Target means that the cost of that overhead is paid on every build, not just builds where parts of the project content changed.

Describe the solution you'd like

The Target should move away from a batching-based call to the Copy Task and instead build up two Item lists of Source and Destination items, then issue one Copy Task call with those source and destination item lists. This reduces the per-Task invocation overhead.

To address the incrementality problem, one of the following approaches should be used:

  • model the inputs/outputs of the Target directly - this will likely require a prior Target to compute the item lists so this Target can make use of them, or
  • set the SkipUnchangedFiles property on the Copy Task call to true to allow the Copy Task to internally-manage the incrementality of the files.

Additional context

This was reported on the 9.0.305 SDK, but would likely apply more broadly.

This Target in particular is interesting because it applies to test projects, which are typically the 'top' of a project-dependency graph. This means they are likely building during periods of low parallelism in the build - they are natural choke-points and so speeding up their linear build times often results in drastically shortening the overall build duration more than you would expect.

Here is a heavily-obfuscated binlog trace chart of a representative workspace:

Image

In this chart, the green area is the 'restore' phase of the build. This entire area can be saved by passing -no-restore, so incremental builds can be quickly shortened in that way.

The dark-blue-bordered areas are the actual 'build' phase - the larger, light-blue area is all of the 'leaf' projects building - core domain logic, webapps built on that logic, utilitiy libraries, etc. Making this area faster is mostly a matter of MSBuild/SDK work IMO. The reddish-orange areas are the test projects, all of which reference this library and another code coverage library (I've logged an issue there as well) - because of the nature of app/test relationships, test projects tend to be the 'last' projects to build and so shortening their build times has a disparate impact on the overall perceived duration of the build.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templatesfeature-mvc-testingMVC testing package

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions