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.
Once installed, to run the Xamarin Profiler from Visual Studio, all you need to do is go to Analyze > Xamarin Profiler.
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.
iOS
Go into the Properties of your iOS project, ensure you enable Debugging and Enable Profiling.
Next, go to the Advanced Tab in the same window, and enable the SGen Generational Garbage Collector.
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.
Once chosen, you will next be presented with the screen that shows the profiling in real time.
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
You can choose from these similar options, to profile your app.
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
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.
This runs far faster, because the UI isn’t constantly updating itself, multiple times per second.
Cross platform mobile developer who loves delving deep into frameworks and solving problems.