Ahead of Time Compilation with Xamarin.Mac

As you might know, .NET applications by default do not compile down to machine code when you build. They compile down to an intermediate layer, called IL, that looks something like this:

During application launch, the mono runtime will Just In Time (JIT) compile this to machine code for you. In many use cases, this works wonderfully and magically behind the scenes.

However, it requires the ability to emit machine code (which can not be done on iOS) and takes some non-trivial amount time. That is why on Xamarin.iOS, builds for device use a “Full“ Ahead of Time (AOT) compilation to compile all needed machine code as part of the build.

Last week, I prototyped a patch that builds upon existing infrastructure in mono to add (AOT) compilation as an option to Xamarin.Mac. It uses a “Hybrid” AOT that compiles a majority of the needed machine code, but allows the runtime to compile needed trampolines and the flexibility to continue to support Reflection.Emit (and other use cases) that currently works on Xamarin.Mac.

This “Hybrid” AOT drastically increases build time, sometimes by more than a minute, but improved application launch time by an average of 20% in my tests.

Despite the small size of the patch, this change is wide reaching in consequence, and will need significant testing before release. My team is working on porting additional Xamarin.iOS tests to our automated test suite and I am going to request QA run our manual tests. In addition, I would like the community to test it out and see what breaks.

To try it out:

Project Options -> Build -> Mac Build-> Additional mmp Arguments

https://github.com/xamarin/xamarin-macios/pull/1340