Telerik blogs

Learn what Jonathan Peppers shared in his .NET Conf 2022 session on .NET MAUI performance updates with the release of .NET 7.

On November 8, 9 and 10 we had the .NET Conf 2022 event, in which the Microsoft team presented super interesting news and improvements in web, mobile, cloud and many more aspects. This time we will summarize Jonathan Peppers’ presentation about Performance Improvements in .NET MAUI (.NET 7 Edition).

Screengrab of Jonathan Peppers beside his slide 'Performance Improvements in .NET MAUI

Goals for .NET 6 & 7

The Microsoft team had two main issues to solve:

  • iOS started fast but the app was big.
  • While in Android, it was the opposite—the application was good but we had problems with the start.

That’s why the goal was 800 milliseconds to display on a Pixel 5. They were also aiming to get around 10 megabytes for the .NET MAUI template on iOS, and they made some really good strides toward those goals in .NET 6.

Goals for .NET 6 & 7 slide, as noted below

But when they started working on .NET 7, they got customer feedback to continue fixing other things like desktop startup, Android layouts and scrolling performance. The team focused on this feedback, but also in .NET 7 they ended up making other improvements to make their apps smaller and able to start faster too.

Android Layout & Scrolling Performance

Slide showing two app screenshots and two graphs. Bullet list says: A CollectionView with 10,000 items, each row contains two data-bound labels, it should scroll fast

This image was already presented in the State of .NET MAUI talk by David Ortinau and Maddy Montaquila. Now let’s dig a little deeper!

This is an app that was on Reddit a few years ago, where labels with text reading “LOL” popped on the screen in random colors and rotations. The app measures how many times it can load another label per second (LOLs per second).

Jonathan wrote his own version of this app. He developed it in Java not in .NET, to later compare Xamarin and .NET MAUI.

When profiling this application, we were able to see some of the performance problems in the layouts in .NET MAUI, and the fixes made can be seen translated in the second image. Here the app is running on a Pixel 4A and consists of:

  • A CollectionView with 10,000 items.
  • Each row contains two data-bound labels.

This is something that you should be able to scroll through quickly. You can see on the device in the first image that as you scroll to the top in .NET 6 you can see the bar is up and in .NET 7 it is lower. It’s a bit tricky to get very exact numbers here, but the graph shown is a very good example to look at for performance of work done.

LOLs per second bar graph showing Xamarin Forms below 200, .NET 6 MAUI above 300, .NET 7 MAUI almost to 500, C# almost to 600, Java almost to 700.

These are LOLs per second. In the previous image, it is referenced how the app was made in Java, C#, .Net MAUI and Xamarin, here we see the result of those tests.

  • Java is like the top of .NET MAUI because you are using the text view of the Android widget, which is the underlying control that is a label in MAUI.
  • The C# version is the same, except we have the cost of C# interop in Java (work will continue to get better and better).
  • At the other extreme, we have Xamarin Forms and .NET MAUI with .NET 6. As you can see from Xamarin Forms to .NET 6, there is considerable progress.

🔗 If you want to know more information, you can enter the LOLs per second documentation.

Desktop Startup Performance in .NET 7

Desktop Startup  in .NET MAUI slide showing the bullet points below and a line chart of startup trends that drops off signifcantly

The following points are highlighted:

  • Windows: Release builds use ReadyToRun by default.
  • macOS/MacCatalyst: Release builds target both x64 and arm64 by default.
  • In one case, the Apple Rosetta translation was taking 3-4 seconds for a .NET MAUI project.

Each of these points were focused on making the experience developing apps with .NET MAUI better and better. Some processes/steps that previously had to be adjusted manually were improved and are already integrated by default.

Profiling and Measuring Startup

Profiling in .NET MAUI Applications slide with bullet list: http://aka.ms/profile-maui; We're working on making this easier! Ideally in a future version of Visual Studio.; Example of dotnet-trace on Android: adb reverse tcp:9000 tcp:9001, adb shell setprop..., dotnet-dsrouter..., dotnet-trace...; https://speedscope.app

Jonathan included documentation called Profiling .NET MAUI Apps in which you can go deeper into the subject!

An example of how to do it on Android is to run a set of commands that sets the .NET Trace to where it might lead your app to run on a remote as an Android device. Therefore, once you run these commands, a speed scope file comes out and you can go to your speedscope.app; it’s like a local web app that doesn’t upload your file anywhere but you can look at your trace on that website.

Measuring Startup Time in .NET MAUI slide with bullets: Always time Release builds!; https://aka.ms/profile-maui#measuring-startup-times; Android: ActivityTaskManager Displayed log message; iOS: Xcode & Instruments; Windows and macOS Desktop code.

For measuring Startup Time in .NET MAUI, you can enter the following documentation. And you can also see in GitHub the measure-startup documentation.

DateTimeOffset.Now and DateTime.Now

DateTimeOffset.Now and DateTime.Now slide bullets: Use UtcNow if you don't need local time; we found a significant amount of time spent in the very first DateTimeOffset.Now call: ~277ms; Event after recording a custom AOT profile, we still saw ~161ms; Instead: 1. Call an Android Java API for the current time offset. Our startup code in the Android workload is Java, so it can easily retrieve the value for use by the BCL. 2. Load timezone data on a background thread. This results in the original BCL behavior when complete, while using the offset from Java in the meantime.; This greatly improved DateTimeOffset.Now to a mere ~17.67ms.

Jonathan was talking about an example of a customer who reported that they were using Datetime.Now in their app and you could see 277 milliseconds being added to the start just by adding this. Turns out they could use UTCNow and that’s what they did.

Jonathan recommends doing this if you don’t really need local time. But in the same way, DataTime.Now is a very common API that is probably still being used despite this, so the Microsoft team worked on improving these times and managed to reduce them from 277 milliseconds to 17 or 18 milliseconds, which is a great improvement.

Other highlighter points:

  • Even after recording a custom AOT profile, they still saw 161ms.
  • Instead:
    • Call an Android Java API for the current time offset. Our startup code in the Android workload is Java, so it can easily retrieve the value for use by the BCL.
    • Load timezone data on a background thread. This results in the original BCL behavior when complete, while using the offset from Java in the meantime.

Some links that Jonathan leaves us as references:

Avoid ColorStateList (int[][], int[])

Avoid ColorStateList slide: dotnet-trace output of a .NET 6 'dotnet new maui' application shows time spent creating Andoird Color StateList objects; You can see details about this method, reviewing the C# binding for this Java API; Creates a Java array and copy each element; Solution - move more of this code into Java!

ColorStateList is an Android API that allows you to bypass a button. For example, all the different states of that button and what color they are—so this is very useful. This API passes a multidimensional array of integers. In the example shown, Java copies all these elements in order to access the array. This took about 17 milliseconds.

The solution for us in .NET MAUI is that we can move the code to Java correctly. MAUI has a space for each platform, so we can put code in there and then we can create our own internal APIs to do things faster by interoperating in Java.

ColorStateList Soluition slide has code blocks

This is an example of what the solution would look like.

Wrapping Up

We have reached the end of this summary. I highlighted some of my favorite topics but there are many more!

If you want to learn more information about this presentation, you can watch the video Performance Improvements in .NET MAUI (.NET 7 Edition), and I also recommend Jonathan Peppers’ article called .NET 7 Performance Improvements in .NET MAUI.

Still haven’t seen the content that was offered at the State of .NET MAUI presentation? I recommend you read the article Recap: State of .NET MAUI—.NET Conf 2022! It speaks about all the news at a general level of .NET MAUI.

Thanks for reading! 💚💕


LeomarisReyes
About the Author

Leomaris Reyes

Leomaris Reyes is a Software Engineer from the Dominican Republic, with more than 5 years of experience. A Xamarin Certified Mobile Developer, she is also the founder of  Stemelle, an entity that works with software developers, training and mentoring with a main goal of including women in Tech. Leomaris really loves learning new things! 💚💕 You can follow her: Twitter, LinkedIn , AskXammy and Medium.

Related Posts

Comments

Comments are disabled in preview mode.