Xcode Instruments Time Profiler Understanding which methods are taking the most time - xcode

My UI is acting choppy and I am trying to understand what the source for this is.
There are a lot of options using Xcode Instruments and I am not sure which set of them are the best for me.
From playing around with some of them it seems that most time is spent in [CALayer drawInContext] and [CALayer layoutSublayers] but I have no idea in what context those methods are called from (what part of the UI is doing that).
Which options should I be choosing in order to better understand?
Also would like to know if there is a way to see what is running in the background which doesn't belong to the current visible UI (I think something in the background may also be thrashing the CPU)

Toogle Display of Primary Views and select:
Separated by Thread
Invert Call Tree
Hide System Libraries
Show Obj-C Only
Try to see this: http://www.raywenderlich.com/23037/how-to-use-instruments-in-xcode

Use the instruments Time Profiler instrument to record your app running on the device during its choppy moments.
Upload the instruments trace at:
http://timeanalyzer.excelsis.com
It will give you a timeline view of your main thread (the main place where UI stutters occur) methods that's a lot easier to visualize than the regular instruments UI. Here's an example view:
http://timeanalyzer.excelsis.com/view.php?jobid=c7f3efc43ff85302a80515b56c0900f0

Related

Application lagging after a limit of widgets

I have a few widgets on my main view, but when I add a new one, it exceeds the "limit" of widgets until it starts lagging. I've tried using different goroutines but I think that in a gui application that's not the case.
Here is a screenshot of before it lags:
and after:
I'm not an expert in this type of problems regarding performance but I don't know why this happens, it seems like there is a sort of limit of widgets before it starts lagging.
I tried even removing the functions from the buttons leaving them with no use, but the program still lags.
If I hide those three buttons though, it doesn't lag anymore.
Anyone is aware of the problem?

What is the recommended frequency for UI changes?

I have a cocoa application window (NSWindow) which position on the screen should be updated frequently (depending on some calculation). As noticed in the documentation, UI changes should be made on the main thread:
void calculationThread()
{
while(true)
{
calculatePosition();
if(positionChanged)
{
dispatch_async(dispatch_get_main_queue(), ^{ setWindowPos(); });
}
}
}
void setWindowPos()
{
[window setFrame:_newFrame display:YES];
}
Now the problem I have is that the window movement is very slow and delayed. After making some profiling I see that the calculation process takes about 40mSec, meaning that I'm queueing up a backlog of UI updates 25 times a second.
I've read here that this might be faster than they can be processed and timer should be used to fire the changes every tenth of a second or so. But, wouldn't it be too slow for the human eye (I mean, in that case the movement wouldn't be delayed but would be lagged causing pretty much the same affect).
I will appreciate some knowledge sharing on this. Actually my main 2 questions are:
Are 25-30 UI updates per second really to much?
If yes, what is the recommended UI changes frequency?
The frequency at which a window can be moved around onscreen without problems will of course depend upon the speed of the user's machine, the video card they have, the size of the window, and probably a bunch of other factors. There is no single good answer to this. However, if you just drag a window around on your screen, you will notice that it can probably be moved very smoothly (unless your machine is very busy or very low on memory or something); I would not expect 25 times per second to produce a problem on a modern Mac. Not even close, in fact.
#RobNapier's points about Core Animation etc. are fine, but overstated I think; there is nothing inherently wrong with changing your UI using a timer or other periodic update if that is what you actually want to do. CoreAnimation is a toolkit for making some types of animation easier; using it is not required, and it is not suited to every problem. Similarly, if you want to make changes that are actually synched to screen refresh then CVDisplayLink is useful, but it doesn't really sound like that's what you want to do.
For your purposes, your basic approach seems fine, although I would suggest adding an NSDate check in order to skip updates if the previous update was less than, say, 1/60th of a second previous. After all, the calculation appears to take 40mSec on your machine, but it might be much faster on some other machine; you want to throttle your drawing to a reasonable rate just to be a good citizen.
So what is the problem, then? I suspect the issue might actually be your call [window setFrame:_newFrame display:YES]. If you look at Apple's docs for that method, they state "When YES the window sends a displayIfNeeded message down its view hierarchy, thus redrawing all views." Each time you call that method, then, you are not only moving your window (which I gather is your intention); you are redrawing all of the contents of the window, too, and that is slow. If you don't need to do that, then that is the overhead you need to eliminate. Call setFrameOrigin: or setFrameTopLeftPoint: instead (which make the semantics clear, that you are moving the window without resizing it or redrawing it), or perhaps just setFrame:display: passing NO instead of YES, and I'm guessing your performance problem will vanish.
If you do in fact need to redraw the window contents every time, then please edit the problem description to reflect that. In that case, the solution will have to involve profiling why your window drawing is slow, and figuring out ways to optimize that, which is an entirely different problem.
As you've discovered, you should never try to drive the UI from a tight loop. You should let the UI drive you. There are three primary tools for that.
For simple problems, AppKit is capable of moving windows around the screen. Just call [NSWindow setFrame:display:animate:]. You can override animationResizeTime: to modify the timing.
In many cases AppKit doesn't give enough control. In those case, the best tool is almost always Core Animation. You should tell the system using Core Animation how you where you want UI elements to wind up, and over what period and path, and let it do the work of getting them there. See the Core Animation Programming Guide for extensive documentation on how to use that. It focuses on animating CALayer, but the techniques are similar for NSWindow. You'll use [NSWindow setAnimations:] to add your animation. Look at the NSAnimatablePropertyContainer protocol (which NSWindow conforms to) for more information. For a simple sample project of animating NSWindow, see Just Say No from CIMGF.
In a few cases, you really do need to update the screen manually at the screen update frequency. I must stress how rare this situation is. In almost all cases, Core Animation is the correct tool. But in those rare case (some kinds of video for instance), you can use a CVDisplayLink to handle this. That will call you each time the screen would like to refresh, giving you an opportunity to update your content to match.

Memory allocation always increasing, despite not using my app

I am currently updating my app, and I have been facing a very strange and complex problem for the last few days. The part of the application that is problematic is made of one UITableViewController that is a list of news, and (after you click on a news) a detail view which is in fact a UICollectionView with as many details CollectionViewCells as there are news.
Each of these can have an infinite amount of elements, and are loaded 20 by 20 when the user scrolls to the bottom of the TableView (or to cell that is at the furthest position right on the CollectionView). Also, inside a DetailsCollectionViewCell, there can be another UICollectionView, containing images.
My problem is that after scrolling a few details views, after behaving normally (ie memory is allocated when I change the page, then stabilize until I change the page again, and so on), the memory allocation start to ramp up slowly but steadily, even if I stop doing anything at all. Also, the CPU usage will go to 100-120% and stay there, whatever I do, even, again, if I don't touch anything. After a while, the UICollectionView and the UITableView will not render any animation anymore, thus loosing the paging, and the inertia when scrolling, and overall resulting in a very poor user experience.
The strange thing is, I can observe these behaviours via XCode 5's Debug Navigator, but when I try to use instrument to find the source of the leaks/allocations, the allocation graph is normal, and I get 40-60 MB mem usage, no more, despite still observing the animations/paging problems.
Has anyone already met such a strange behaviour, and can someone help me in finding the cause of all this fuss ? (maybe by fixing Instruments ?)
Thank you all in advance, don't hesitate to ask me for more infos if needed !
I found the solution to my problems in the meantime.
About the difference in Memory usage between Xcode 5's Debug Navigator and Instruments, it was caused by my use of NSZombies. I have the habit of always setting them on, and that just flew off my mind... To remove them : Product > Scheme > Edit Scheme > Diagnostics > Enable Zombie Objects (just unmark it).
The cause of my CPU usage was an animation that was going on indefinitely in the background on multiple pages. The solution was to first of all stop it as soon as it is not seen/useful anymore, the optimise it by changing my approach (I was using CAAnimation and moved on to using UIView's animate function).
I think I might have pulled the trigger a bit too fast here, but hey... if this can help someone later, then it will not be a waste !

What could possibily slow down my flex mobile application?

I am working with flex for the last two years on some desktop apps. Until now I never had any performance related issues but today as we completed a mobile application for the iPad, I'm facing a challenge, the application is incredibly slow on the iPad.
http://i.stack.imgur.com/qkbWn.png
Slow, means that when I press a button in the menu to change the splitview I must wait something like 5s. Then scrolling is really slow two, with less than one fps and my TextInput starts to bug (the text is not in his box anymore).
I started to read a lot of blog post and presentation about optimisation for the mobile platform and then I rewrite some of the components I use. I removed the SkinnableContainer for instance and replaced it by a VGroup including some actionScript based drawing.
Now what you see is a VGroup (the dark grey one) containing some others VGroup (the group with title here) and then each widget is an HGroup with a label and a Widget. I only use Label and TextInput for the text.
Creation time is slow even (several seconds to create the view) for another page where there is only 4 text widget on it, or another one with only a list with a custom item renderer where each row is a set of 4 labels.
The whole things is cabled with RobotLegs, with nothing fancy, one models is injected in the view and at the beginning I set a member variable on the view with this object to bind my variables.
Frankly my thinking right now is : it smells fishy because if I've done everything right it is impossible to have such low performance and thinks that flex is competitive on the mobile platform. So right now I'm trying to disable the application piece by piece to try to locate what could slow it like that. I've got a couple suspects to check, for instance I've got some binding warning to check, and then see if robotlegs has got its share of the problem.
So my main question here is what do you think, and could you have some ideas about "is there a problem" and "how do we solve it".
Thanks
Run profiler for startup and separatelly for each operation that takes longed that it needs. Then prioritize the problems and try to solve them with basic optimization techniques.
Some problems you will not be able to solve fast - e.g. time for creating big components. The only option there is to rewrite those components with AS3 without MXML, styles and anything. I'm sure that flash.text.TextField is created many times faster than mx.controls.Label. The same for other components.
When component is created, it can be reused at a very low price. In your app there must be a lot of places where you recreate while you can reuse old components. It will save you memory and time.
Layouts tend to redraw even when it's not needed. If you have a lot of nested layouts, find the most critical places and replace a series of layouts with one custom layout or even component.
This all is very developer time consuming. At the end you will not get a smooth app anyway, but I believe that it can become usable.

Timing execution and loading in Silverlight

I'm trying to determine some testing strategies for a Silverlight application of ours.
What I'd like to determine is the total time it takes for a grid to load and show data in the client. I've tried to put a timer round assigning the itemsource, but I need to know how long it takes the browser is finish loading the data into the grid.
Is this at all possible? If so, in what direction do I've to search?
This might help an article on MSDN "Loaded event timing in Silverlight"
http://blogs.msdn.com/b/silverlight_sdk/archive/2008/10/24/loaded-event-timing-in-silverlight.aspx
I think the main idea is to make use of the LayoutUpdated event. Since the event hangs off the FrameworkElement object I guess you could add a handler to all controls and effectively profiler all the framework elements of your Silverlight app. Something similar to the MVC Mini Profiler (SO uses/created this). http://code.google.com/p/mvc-mini-profiler/
I would certainly explore the LayoutUpdated event further.

Resources