Skip to content

Commit

Permalink
[core] use Lazy<T> for MauiContext properties
Browse files Browse the repository at this point in the history
Context: https://github.com/unoplatform/performance/tree/master/src/dopes/DopeTestMaui

Building upon dotnet#7996 and dotnet#8001, I noticed while profiling the sample
app putting N `Label` on the screen:

    405.02ms (2.3%) microsoft.maui!Microsoft.Maui.MauiContext.get_Context()
    77.90ms (0.44%) microsoft.maui!Microsoft.Maui.MauiContext.get_Handlers()

Meaning that around ~2.74% of the time was spent just calling these two
properties. These properties hit Microsoft.Extensions each time to
locate the service:

    public Android.Content.Context? Context => _services.GetService<Android.Content.Context>();

These are core-services that wouldn't change after
startup, so should we just use `Lazy<T>` instead of doing a call like
this each time?

I also made use of `ANDROID`, as that is the preferred define to use
in .NET 6+ instead of `__ANDROID__`:

https://github.com/dotnet/designs/blob/a447d77bb53d189746ccd80c2d814064c2b6c606/accepted/2020/net5/net5.md#vary-implementation

~~ Results ~~

A `Release` build on a Pixel 5 device, I was getting:

    Before: 81.70 Dopes/s
    After:  91.94 Dopes/s
  • Loading branch information
jonathanpeppers committed Jun 15, 2022
1 parent a6ecf6f commit 5c4a499
Showing 1 changed file with 11 additions and 8 deletions.
19 changes: 11 additions & 8 deletions src/Core/src/MauiContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ namespace Microsoft.Maui
public class MauiContext : IMauiContext
{
readonly WrappedServiceProvider _services;
readonly Lazy<IMauiHandlersFactory> _handlers;

#if ANDROID
readonly Lazy<Android.Content.Context?> _context;

public Android.Content.Context? Context => _context.Value;

#if __ANDROID__
public MauiContext(IServiceProvider services, Android.Content.Context context)
: this(services)
{
Expand All @@ -19,17 +24,15 @@ public MauiContext(IServiceProvider services, Android.Content.Context context)
public MauiContext(IServiceProvider services)
{
_services = new WrappedServiceProvider(services ?? throw new ArgumentNullException(nameof(services)));
_handlers = new Lazy<IMauiHandlersFactory>(() => _services.GetRequiredService<IMauiHandlersFactory>());
#if ANDROID
_context = new Lazy<Android.Content.Context?>(() => _services.GetService<Android.Content.Context>());
#endif
}

public IServiceProvider Services => _services;

public IMauiHandlersFactory Handlers =>
Services.GetRequiredService<IMauiHandlersFactory>();

#if __ANDROID__
public Android.Content.Context? Context =>
Services.GetService<Android.Content.Context>();
#endif
public IMauiHandlersFactory Handlers => _handlers.Value;

internal void AddSpecific<TService>(TService instance)
where TService : class
Expand Down

0 comments on commit 5c4a499

Please sign in to comment.