You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[Xamarin.Android.Build.Tasks] use System.Reflection.Metadata in <ResolveAssemblies/>
Context: https://github.com/dotnet/corefx/tree/master/src/System.Reflection.Metadata/src/System/Reflection/Metadata
Context: https://github.com/jonathanpeppers/Benchmarks
There is a new System.Reflection.Metadata library from corefx for
reading .NET assemblies. It is a bit more performant than Mono.Cecil
because it is a different library with different opinions.
Some notes about System.Reflection.Metadata:
- SRM has a forward "reader" style API
- SRM uses lots of structs, and you have to do an additional call to
lookup strings generally.
- SRM, as far as I have seen, doesn't have APIs to modify and write
out new assemblies.
- SRM only supports "portable" pdb files.
- SRM is not well documented yet. To discover usage, I read source
code and/or unit tests.
From my benchmark above, it seems that SRM is 10x faster on
Windows/.NET framework and 5x faster on macOS/Mono.
So it makes sense for use to use SRM when reading assemblies (and we
don't need symbols), and continue with Mono.Cecil for the linker and
other things that modify assemblies.
There are a few places we can take advantage of SRM, but the simplest
with a reasonable impact was `ResolveAssemblies`:
Before:
320 ms ResolveAssemblies 1 calls
After:
112 ms ResolveAssemblies 1 calls
So a ~200ms savings on this MSBuild task, which runs on *every* build.
This was the Xamarin.Forms test project in this repo: a build with no
changes.
~~ Changes ~~
- Added a `MetadataResolver` type, as a way to cache `PEReader`
instances. This is a comparable drop-in replacement for
`DirectoryAssemblyResolver`.
- `MonoAndroidHelper.IsReferenceAssembly` now uses
`System.Reflection.Metadata` instead of `Mono.Cecil`. This is used
in a few other MSBuild tasks.
- A `MetadataExtensions` provides an extension method to simplify
getting the full name of a custom attribute. We can add more here as
needed.
- Had to adjust the filename reported for XA2002, should optionally
call `Path.GetFileNameWithoutExtension` if the name ends with
`.dll`.
The resulting code *should* be the same, except we are using SRM over
Mono.Cecil.
~~ Other changes ~~
[xabuild.exe] remove SRM reference
This appears to fix the build on macOS, we had this workaround from a
mono bump in the past. Since xabuild has its own version of
System.Reflection.Metadata that was already loaded, we weren't loading
the one we are using in XA's MSBuild tasks.
Things appear to work without the reference now.
~~ Downstream ~~
We will need to add the following assemblies to the installer:
- `System.Reflection.Metadata.dll`
- `System.Collections.Immutable.dll`
0 commit comments