Skip to content

Investigate limitations and document findings of enabling NativeAOT for MAUI iOS application #80907

Closed

Description

@ivanpovazan

Description

Investigate potential issues and limitations of NativeAOT with .NET MAUI iOS applications:

  1. .NET MAUI template app
  2. .NET MAUI Podcast app

Goals

  • Document discovered findings and limitations
  • Based on the results propose the follow-up work
  • Measure performance of NativeAOT targeting iOS platforms, and compare results against MonoAOT, the measurements should include: the application size: disk size (SOD) and bundle size (.ipa), build and startup time

Preview 6

Our main focus for the initial releases is the application size.
Apps were built and measured using: https://github.com/xamarin/xamarin-macios/tree/release/8.0.1xx-preview6 release

.NET MAUI template app

Building a .NET MAUI iOS sample application dotnet new maui gives the following results:

.NET MAUI ios app Mono-p6 NAOT-p6 diff (%)
SOD (Mb) 40,24 50,13 25%
.ipa (Mb) 14,68 16,59 13%

Mono-p6 in the table represents results obtained with Mono .NET8 preview6, while NAOT-p6 represents results obtained with NativeAOT .NET8 preview6

Identified issues that contribute to the size regression with NativeAOT are:

Estimated savings

  • Estimated savings in app sizes by applying optimizations for NativeAOT from Step1 to Step4

    .NET MAUI ios app Mono-p6 NAOT-p6 Step1 Step2 Step3 Step4
    SOD (Mb) 40,24 50,13 41,93 40,5 27,58 TBD
    .ipa (Mb) 14,68 16,59 13,43 12,85 10,23 TBD

    NOTE: Results for StepN mean that all the previous steps Step1..N have been implemented

  • Estimated difference (%) in app sizes compared to Mono-p6 by applying optimizations for NativeAOT from Step1 to Step4

    .NET MAUI ios app Mono-p6 NAOT-p6 Step1 Step2 Step3 Step4
    diff SOD (%) NaN 24,56% 4,20% 0,64% -31,46% TBD
    diff .ipa (%) NaN 13,00% -8,53% -12,48% -30,32% TBD

    NOTE: Diffs in the table mean that if for example we implement Step1 and Step2, the .ipa size with NativeAOT will be 12,48% smaller compared to Mono

.NET MAUI Podcast app

Estimated savings

  • Preliminary data (only estimated for Step3 improvements with NativeAOT):

    .NET MAUI ios app Mono-p6 Step3 diff (%)
    SOD (Mb) 62,67 43,59 -30,45%
    .ipa (Mb) 24,37 17,43 -28,47%

Preview 7

Apps were built and measured using: https://github.com/xamarin/xamarin-macios/tree/release/8.0.1xx-preview7 release. The results show that NativeAOT generates ~30% smaller applications compared to Mono (as it has been estimated above).

.NET MAUI template app

MAUI ios app Mono-p7 NAOT-p7 diff (%)
SOD (Mb) 40,52 27,41 -32,37%
.ipa (Mb) 14,82 10,14 -31,56%

.NET MAUI Podcast app

MAUI podcast app Mono-p7 NAOT-p7 diff (%)
SOD (Mb) 62,81 42,18 -32,84%
.ipa (Mb) 24,46 16,85 -31,10%

Other findings

  • Fix Infinite recursion when generated code wrongly dispatches explicit interface calls
  • Objective-C interop and GC API support:
  • Support static registrar with NativeAOT:
  • Dynamic registrar with NativeAOT - [NOT A PROBLEM]
    • We did not detect any need to support dynamic registrar with NativeAOT so far - especially because NativeAOT does not seem to be required for inner-dev loop experience. Nevertheless, bellow are listed findings when dynamic registrar is enabled for NativeAOT:
      • When building the application with dynamic registrar, the application crashes when ObjC runtime tries to register UIKit.UIGestureRecognizer+Callback`1 type while it is fetching its interface map against Foundation.INSObjectProtocol:
      default 12:06:26.833235+0200    HelloMauiiOS    *** Terminating app due to uncaught exception 'System.ArgumentException', reason: 'Interface not found. (System.ArgumentException)
      at Internal.Reflection.Execution.ExecutionEnvironmentImplementation.VerifyInterfaceIsImplemented(RuntimeTypeHandle, RuntimeTypeHandle) + 0x78
      at System.Reflection.Runtime.TypeInfos.RuntimeTypeInfo.GetInterfaceMap(Type) + 0xa8
      at Registrar.SharedDynamic.PrepareInterfaceMethodMapping(Type) + 0x114
      at Registrar.Registrar.RegisterTypeUnsafe(Type, List`1&) + 0x1fbc
      at Registrar.Registrar.RegisterType(Type, List`1&) + 0x44
      at Registrar.DynamicRegistrar.Register(Type) + 0x18
      at ObjCRuntime.Class.GetClassHandle(Type, Boolean, Boolean&) + 0x168
      at Foundation.NSObject.AllocIfNeeded() + 0x40
      at UIKit.UIPanGestureRecognizer..ctor(Action`1) + 0x40
      at Microsoft.Maui.Controls.Platform.Compatibility.ShellFlyoutRenderer.Microsoft.Maui.Controls.Platform.Compatibility.IShellFlyoutRenderer.AttachFlyout(IShellContext context, UIViewController content) + 0xf8
      

Activity

  1. added this to the 8.0.0 milestone on Jan 20, 2023
  2. self-assigned this
    on Jan 20, 2023
  3. ivanpovazan commented on Aug 1, 2023

    @ivanpovazan
    MemberAuthor

    I have updated the description with the latest - preview 7 results.
    The results show that we reached what was estimated in preview 6 release.

    I am closing this issue as we identified the limitations and opened tracking issues for them.

  4. ghost locked as resolved and limited conversation to collaborators on Aug 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

  • Status
    No status

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions