Skip to content

Conversation

@jonathanpeppers
Copy link
Member

@jonathanpeppers jonathanpeppers commented Aug 4, 2020

In a customer's build log, a large solution build with no changes had:

1956 ms  FilterAssemblies                          18 calls

The <FilterAssemblies/> MSBuild task runs on every build for class
libraries and application projects. It looks at assemblies to classify
them as a "MonoAndroid" assembly.

Since we are already using System.Reflection.Metadata to open each
assembly, we can use each assembly's MVID and RegisterTaskObject to
skip future calls to the same assembly. This will be helpful in
incremental builds in the IDE, as well as, large solutions that
encounter the same assemblies throughout a build.

Using the in-memory cache, we don't need to check any file timestamps.
Unique MVIDs will yield the same result for the <FilterAssemblies/>
task -- regardless if the assembly was built with $(Deterministic)
or not.

Results

I did not have access to the original customer project, so I tested
this change using xamarin/Xamarin.Forms@d9926450 instead. There
are 8 Xamarin.Android projects during the build.

Before:
165 ms  FilterAssemblies                          16 calls
After:
156 ms  FilterAssemblies                          16 calls
After (with MSBuild node running):
 99 ms  FilterAssemblies                          16 calls

Even on the first build, many assemblies are pulled from the cache. It
printed ~326 instances of this log message:

Task "FilterAssemblies"
...
    Cached: C:\src\Xamarin.Forms\Xamarin.Forms.Platform.Android.FormsViewGroup\bin\Release\FormsViewGroup.dll

This saves ~10ms from an initial build of Xamarin.Forms' source and
~66ms from incremental builds. This will have a bigger impact on
larger solutions.

Other changes

I removed an unused DesignTimeBuild property from
<FilterAssemblies/>.

I removed the log message:

// In the rare case, [assembly: TargetFramework("MonoAndroid,Version=v9.0")] may not match
Log.LogDebugMessage ($"{nameof (TargetFrameworkIdentifier)} did not match: {assemblyItem.ItemSpec}");

It is actually not a "rare" case, it was printed 330 times from the
customer's log. This log message didn't add much value, so I removed
it to reduce string allocations.

@dotnet dotnet deleted a comment from azure-pipelines bot Aug 4, 2020
@jonathanpeppers jonathanpeppers marked this pull request as ready for review August 4, 2020 14:57
In a customer's build log, a large solution build with no changes had:

    1956 ms  FilterAssemblies                          18 calls

The `<FilterAssemblies/>` MSBuild task runs on every build for class
libraries and application projects. It looks at assemblies to classify
them as a "MonoAndroid" assembly.

Since we are already using System.Reflection.Metadata to open each
assembly, we can use each assembly's MVID and `RegisterTaskObject` to
skip future calls to the same assembly. This will be helpful in
incremental builds in the IDE, as well as, large solutions that
encounter the same assemblies throughout a build.

Using the in-memory cache, we don't need to check any file timestamps.
Unique MVIDs will yield the same result for the `<FilterAssemblies/>`
task -- regardless if the assembly was built with `$(Deterministic)`
or not.

~~ Results ~~

I did not have access to the original customer project, so I tested
this change using xamarin/Xamarin.Forms@d9926450 instead. There
are 8 Xamarin.Android projects during the build.

    Before:
    165 ms  FilterAssemblies                          16 calls
    After:
    156 ms  FilterAssemblies                          16 calls
    After (with MSBuild node running):
    99 ms  FilterAssemblies                          16 calls

Even on the first build, many assemblies are pulled from the cache. It
printed ~326 instances of this log message:

    Task "FilterAssemblies"
    ...
        Cached: C:\src\Xamarin.Forms\Xamarin.Forms.Platform.Android.FormsViewGroup\bin\Release\FormsViewGroup.dll

This saves ~10ms from an initial build of Xamarin.Forms' source and
~66ms from incremental builds. This will have a bigger impact on
larger solutions.

~~ Other changes ~~

I removed an unused `DesignTimeBuild` property from
`<FilterAssemblies/>`.

I removed the log message:

    // In the rare case, [assembly: TargetFramework("MonoAndroid,Version=v9.0")] may not match
    Log.LogDebugMessage ($"{nameof (TargetFrameworkIdentifier)} did not match: {assemblyItem.ItemSpec}");

It is actually not a "rare" case, it was printed 330 times from the
customer's log. This log message didn't add much value, so I removed
it to reduce string allocations.
@jonathanpeppers
Copy link
Member Author

The one failing Build_CSharp_Change looks OK:

Exceeded expected time of 3350ms, actual 3400.245ms

It's not the task I changed:

image

@jonathanpeppers jonathanpeppers merged commit a963c30 into dotnet:master Aug 5, 2020
@jonathanpeppers jonathanpeppers deleted the filterassemblies-inmemory branch August 5, 2020 12:52
jonpryor pushed a commit that referenced this pull request Aug 10, 2020
)

In a customer's build log, a large solution build with no changes had:

    1956 ms  FilterAssemblies                          18 calls

The `<FilterAssemblies/>` MSBuild task runs on every build for class
libraries and application projects. It looks at assemblies to classify
them as a "MonoAndroid" assembly.

Since we are already using System.Reflection.Metadata to open each
assembly, we can use each assembly's MVID and `RegisterTaskObject` to
skip future calls to the same assembly. This will be helpful in
incremental builds in the IDE, as well as, large solutions that
encounter the same assemblies throughout a build.

Using the in-memory cache, we don't need to check any file timestamps.
Unique MVIDs will yield the same result for the `<FilterAssemblies/>`
task -- regardless if the assembly was built with `$(Deterministic)`
or not.

~~ Results ~~

I did not have access to the original customer project, so I tested
this change using xamarin/Xamarin.Forms@d9926450 instead. There
are 8 Xamarin.Android projects during the build.

    Before:
    165 ms  FilterAssemblies                          16 calls
    After:
    156 ms  FilterAssemblies                          16 calls
    After (with MSBuild node running):
    99 ms  FilterAssemblies                          16 calls

Even on the first build, many assemblies are pulled from the cache. It
printed ~326 instances of this log message:

    Task "FilterAssemblies"
    ...
        Cached: C:\src\Xamarin.Forms\Xamarin.Forms.Platform.Android.FormsViewGroup\bin\Release\FormsViewGroup.dll

This saves ~10ms from an initial build of Xamarin.Forms' source and
~66ms from incremental builds. This will have a bigger impact on
larger solutions.

~~ Other changes ~~

I removed an unused `DesignTimeBuild` property from
`<FilterAssemblies/>`.

I removed the log message:

    // In the rare case, [assembly: TargetFramework("MonoAndroid,Version=v9.0")] may not match
    Log.LogDebugMessage ($"{nameof (TargetFrameworkIdentifier)} did not match: {assemblyItem.ItemSpec}");

It is actually not a "rare" case, it was printed 330 times from the
customer's log. This log message didn't add much value, so I removed
it to reduce string allocations.
@github-actions github-actions bot locked and limited conversation to collaborators Jan 24, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants