Xamarin Forms Profiling

Profiling is about finding resource usage that is out of place. Resources can include, network traffic, CPU, GPU, storage and/or memory usage. Because every app can behave differently, there is no set profile on how resource usage should look for your app, only guidelines. This means a profiler doesn’t give you any guidance, or show you obvious mistakes, you have to interpret them.

There are 2 profilers you can use. The Xamarin Profiler for iOS and Android, and the Performance Profiler for UWP apps. The Xamarin Profiler is only available on Enterprise licensing. However the Performance Profiler is available on lower versions. Just another reason, it’s always handy to have a UWP app, for your Xamarin Forms application.

Xamarin Profiler Setup

First you must download the Xamarin Profiler, and install the application.

xamarin-profiler-setup

Once installed, to run the Xamarin Profiler from Visual Studio, all you need to do is go to Analyze > Xamarin Profiler.

analyze

But before we do that we need to ensure our iOS and Android apps are setup to be profiled.

Android

Go into the Properties of your Android project, then the Android Options tab, and ensure that Debugging is switched on and the debugger set to Xamarin.

androiddebugging

iOS

Go into the Properties of your iOS project, ensure you enable Debugging and Enable Profiling.

debugging

Next, go to the Advanced Tab in the same window, and enable the SGen Generational Garbage Collector.

sgen

Running Xamarin Profiler

Next, if we run the Profiler, we get to choose which instruments we will use to be profiled, over time. One of the most common metrics you will look at, are the allocations, which also detail the total memory usage.

choose-an-instrument-template

Once chosen, you will next be presented with the screen that shows the profiling in real time.

xamarinprofiler

At the bottom of the screen, if you selected Allocations, are a list of allocations made. If you are looking at this and not understanding how you are meant to action this data, there is only one thing you really need to look for, and that is anomalies. You look at these details later. But what is an anomaly?

Noticing Anomalies

Anomalies normally come in different trends depending on what is happening. They are something that looks, out of place.

Memory

Memory can have 2 types of anomalies. First is the continuous upward trend. Where every page, or action taken, leads to more memory being consumed, but never released. Second, is large spikes, even if they are being released. This may be due to a large image, particularly in Android, being loaded.

CPU

CPU can show 2 types of patterns. Prolonged 100% CPU usage, or prolonged high CPU usage. This is normally anything above 2-3 seconds would be a concern. 2-3 seconds of 100% CPU usage would be a large concern as this will impact your UI responsiveness.

Second are spikes but you have to look closely. CPU spikes will be common as you move around your app, however if your aren’t interacting with your app and you continuously see spikes still occurring, it may mean a background thread is up to something it shouldn’t be.

App responsiveness and battery life are the two major impacts of CPU usage.

Performance Profiler

The performance profiler comes with Visual Studio and is great to profile UWP apps. I really love having a UWP project, in my Xamarin Forms app, if only for this reason. While it can’t pick out platform specific issues with your native Android and iOS code, it does give a great picture on your non-framework, Xamarin Forms code.

To profile and app, go to Analyze > Performance Profiler

analyzeperformanceprofiler

You can choose from these similar options, to profile your app.

uwpprofileoptions

Demo

In order to give you an idea of how to detect an anomaly in an app, this is an example showing high CPU usage. Then we will change the code, to resolve the error and show the new profile. As the example, there will be a label on a page, that we will assign to.

UWP High CPU Usage

First, we start off by looping, 100,000 times and adding the count to a label.

protected override void OnAppearing()
{
    base.OnAppearing();

    for (var i = 0; i < 100000; i++)
        TestLabel.Text += i.ToString();
}

This is its CPU profile

uwpcpuprofile_highusage

UWP Reduced CPU

To resolve this issue, we will now create the text first, with a StringBuilder, then only assign to the label once.

protected override void OnAppearing()
{
    base.OnAppearing();

    StringBuilder b = new StringBuilder();
    for (var i = 0; i < 100000; i++)
        b.Append(i.ToString());

    TestLabel.Text = b.ToString();
}

Now, we can run the profiler again and see how this code performs.

uwpcpuprofile_highusagefix

This runs far faster, because the UI isn’t constantly updating itself, multiple times per second.


Posted

in

by

Tags: