I don't see any way to start/stop profiling in Instruments from code, which kinda kills its usefulness for me in a large number of situations.. Am I missing something? Does anyone know of a way to do this?
The fallback approach is to grab performance data on my own, without Instruments. Has anyone tried to do this before? By "performance data" I mean counts of events like cache misses, fills, missed branches, etc.
Thanks!
Update:
I looked into operating the performance monitor hw directly from code, but, unsurprisingly, it appears to be a no-go. USEREN, the "user enable register" controls access to perfmon registers but is not enabled. It might be possible to run privileged or enable user access with a jailbroken phone, but that's a lot of work for some basic profiling.. ugh.
Related
I need to measure the performance of a couple of lines of code in my iPhone app. I have a macro that does the job well, but it writes the output to NSLog afterwards (with a delay to make sure that NSLog does not affect the actual performance measurement), so I always have to attach the debugger to the device to get the results.
Now I am wondering if and how the debugger affects performance of the App, eg. I imagine it doesn't affect disk reading/writing commands but probably eats up some CPU time. Are there any docs on this topic? What tools are out there to get performance measurements of apps without the effect of the debugger?
In addition to David's answer, I would say, why don't you try it?
In Xcode 4, go to Product > Edit Scheme... > Run action > Info tab and choose Debugger "None". This way the debugger is disabled and you can test the way you like.
From what I have experienced, other than a jump in RAM there's no difference at all.
However, if you debug using NSZombieEnabled, you can experience some lags.
I am using instrument "Allocations" to monitor the app's memory. The vm tracker statistics puzzled me. Why there is so much dirty memory(for my app, reach 32M), I googled about this and knew that the dirty memory should be clear first when app received memory warning in background mode.
Could you tell me about the meaning of vm checker statistics? And how can I handle the dirties:VM_ALLOCATE, Core Animation.
Thanks in advance!
There is often very little you can do about VM usage directly; much of that will be due to use of various system APIs, etc...
Your time will be far more productively spent by focusing on the objects in the Allocations instrument itself and work towards both eliminating any leaks (accretion, too, not just leaks) and reducing allocation bandwidth.
What are the best practices, tricks, and tutorials for using XCode's performance tools, such as the Leak Monitor and the CPU sampler, for someone trying to debug and enhance performance of an iPhone application?
Thanks!
It depends entirely on the application and on what you are trying to do. Are you trying to optimize the whole application or are you focused on a particular problem area? Are you trying to reduce memory usage, reduce CPU usage, and/or make the app more responsive?
Before you start the performance analysis, use the static analyzer to analyze your code. It will often find memory management problems that would lead to leaks that would cause your app to potentially crash on the device.
Once all of the analyzer identified problems have been fixed, the best approach is to start by identifying perceived performance problems. That is, focus on performance problems that the user would notice. Then analyze those. If you can get away with it, do the analysis on the app running in the simulator as the turnaround time is faster.
If the problem is one of bloat, use Object Alloc and Leaks to figure out why.
If it is one of laggy/sluggish behavior, use the CPU tools to figure out where the cycles are going. Keep in mind, though, that sluggish behavior may not be because of CPU usage, but may be because the main event loop is blocked by something, most likely incorrect concurrency patterns. In that case, you'll see all samples on the main thread in some kind of a lock or wait function.
Beyond that, you'll need to identify specific scenarios to yield specific answers.
use instruments in that use
object allocation
activity monitor,
leaks
memoer monitor
and test your app
To be clear, this is for a normal iPhone application, and not a game.
I've read around the web a few times some developers mentioning that they were working hard to improve/reduce the startup time of their applications, but never with any good background information on how to do so.
So the question is simple: how can you reduce the startup of iPhone applications?
Same as any other performance issue: Use Shark and/or Instruments to identify bottlenecks in your code, and then focus on how you can speed things up there. Each tool will give you a picture of how much time was spent in what parts of your code, so the general scheme would be to run the tool while you start the app and then pore over the data to see where the performance hits occur.
At app startup time, the most likely candidates for improvement will be deferring data loading until later on when it's actually needed, variously described as "on demand" or "lazy" loading. Essentially, don't load any data at app startup unless it's actually needed right away when the app loads. In practice, lots of stuff that may be needed at some point doesn't have to be immediately available when the app starts. For example, if you have a database of N records but only one is visible at a time, don't load all N into memory at app startup time. Load whatever the current record is and then load the others when you actually need them.
James Thomson did a nice blog post documenting his efforts to make PCalc launch faster.
Of particular interest is his use of image with screenshot from last app run, to pull the same trick Default.png does, while loading rest of the app.
Need advice on how to debug this. I'm new with limited environments and have no previous embedded or smart phone programming experience so I could use some clues.
Already aware of:
Instruments, Clanger Static Analysis, manual code review, etc. Instruments seems to be very helpful in general but quite time consuming and freezes up a lot of the time! Clanger has also helped me a lot as well. It seems like I'm just consuming too much memory in general and I'm wondering what a good strategy is. Do I release some top-level objects? Is there a 'preferred strategy'?
Just wondering if anyone has tackled this successfully and if they have any other suggestions? Thanks all.
There are a lot of good articles for memory management in an iPhone app. Here are some useful links.
http://iosdevelopertips.com/objective-c/memory-management.html
http://kosmaczewski.net/2009/01/28/10-iphone-memory-management-tips/
https://cocoa-touch.blogspot.com/2008/09/memory-management-on-iphone.html
Things you should in general take care of
Release any variables which you do not need
Always handle didReceiveMemoryWarning and release any variables not in use
Stop any memory-heavy processes in applicationDidReceiveMemoryWarning like audio/video playing, UIImagePickerController etc
EDIT
This does not apply any more. imageNamed: had caching issues prior to 3.x OS versions. The issue does not exist any more and you should use imageNamed: (makes implementing retina display easier)
Do NOT use imageNamed: to create UIImage objects.
Basically you're receiving this warning because (unsurprisingly) the iPhone is dangerously low on memory. This can generally be for one of two reasons;
You have a memory leak.
You are allocating far too many objects and need to revisit your design.
For the first one you should run instruments and examine your memory allocations. This can really slow down your app (and requires additional memory) so try testing areas of your app one at a time. E.g. if you have multiple views switch between them a couple of times.
For the second you will have to examine things you are doing that could result in large memory allocations. For example if you're writing a Flickr browser you might need to cut down the number of images you have loaded at anyone time, or free up some unused ones when you receive this warning.
These are about the only general rules I can suggest without knowing more about your app.
Unfortunately there's no real way (that I know of) to get figures for current memory allocation from the iPhone OS. This makes it really difficult to isolate the areas of your application that are inadvertently memory hungry.