Exploring the Instruments suite

In this book's code bundle, you'll find a project named Mosaic. The app is still in the early stages of development, so there is plenty of work that needs to be done to improve it. More specifically, the app doesn't seem to work very well.

Even though the app isn't finished and the code isn't perfect, the app should be working fine. None of the features appears to be very performance-heavy, so the app works fine. If you launch the app and click around, you'll notice that the app isn't working fine. It's really slow! Let's see how you can track down the exact cause of the slowness.

If you dig through the source code, you'll immediately see that the app has three main screens:

  • A table view
  • A collection view
  • A detail view

The table view displays a list of 50 items, each of which links to an infinitely-scrolling collection view with a custom layout. The layout for the collection view is custom because it needed to have exactly one pixel of spacing between items. The detail view only shows an image, nothing too crazy.

Based on knowledge from earlier chapters, you should know that a simple app such as Mosaic should be able to run smoothly on virtually any iOS device. Collection views and table views are optimized to display huge datasets, so an endlessly-scrolling collection view that keeps adding 50 new rows when you almost reach the end of the list should not be too much of a problem. In other words, this app should be able to run at 60 frames per second with no trouble at all.

However, if you start scrolling through the collection view and move back and forth between screens, and then scroll more and more, you'll find that some collections will stop scrolling smoothly. They will randomly freeze for a little while and then continue scrolling. And the more you scroll through the collections, the worse this issue seems to become.

If you take a look at the memory usage in Xcode's Debug navigator (the sixth icon in the left sidebar), you can tell that something is wrong because memory usage keeps going up while navigating through screens. This in itself is nothing to worry about, temporary memory spikes are normal. When the used memory never gets freed even though you might have expected it to, that's when you should start worrying. Take a look at the following graph:

Whenever you debug performance issues or if you're trying to measure performance, make sure to measure on a real device. If you measure using the simulator, your app might run fine even though it might not run fine on a device. This is due to the way the simulator works. It mimics an iOS device, but it's backed up by all the power your Mac has to offer. So, the processor and available memory are those of your Mac, resulting in performance that's often much better than it would be on a device.

For now, make a mental note of the app's rising memory usage. Let's have a look at the Instruments app. To profile your app with Instruments, you can either select Product | Profile from the Xcode's toolbar or hit Cmd + I on your keyboard. Xcode will then build your project and launch Instruments so you can select a profiling template:

There are many available templates, and most of them are created for a specific case. For instance, the Network template will measure network usage. There are also templates available to profile animations, database operations, layout, Metal graphics performance, and more.

If you select a blank template, you're presented with the Instruments interface. The interface contains a record button that is used to start or stop profiling for an app. If you look further to the right side of the top toolbar, there's a plus icon. You can use this icon to add profiling tools for specific metrics yourself. You could use this to create a profiling suite that fits your needs without having to switch between the default templates all of the time. The center of the Instruments interface is the timeline. This is where graphs are drawn, representing the measurements that were made for your app. The bottom section of the screen shows detail about the currently selected metric, as you're about to find out:

Now that you know a little bit about the interface of the Instruments app, let's make an attempt at profiling the Mosaic app. The biggest issue in the app is the choppy scrolling when you scroll down the collection view for several pages. It's clear that the app has a memory issue, as you saw in Xcode, but choppy scrolling occurs even if the app's memory usage is low. This should be a flag that a memory leak probably isn't the problem that is causing the collection views to scroll badly. Something in the code is probably slow, and Instruments can help to figure out which parts of the app's code are taking a long time to complete.