anyway to see method execution times in Xcode? - iphone

I need to debug a certain ViewController I have and I can't seem to pinpoint exactly what is causing my lag time for the view to show.
IS there any debugger tool in Xcode that will show me how long my methods are taking to run so i can at least find the right place to start?

Instruments has a profiler built into it ever since iOS 4.0 (before which you used a stand-alone profiler tool called Shark).
Here's a quick little tutorial that will get you started: http://blancer.com/tutorials/flex/78335/apple-profiling-tools-shark-is-out-instruments-is-in/
If you don't know about Instruments, you should. It's how you know what's really going on inside your code while it runs.

Apart from Time Profiler as suggested by Dan you can also use Sampler instrument which generally stops a program at prescribed intervals and records the stack trace information for each of the program’s threads. You can use this information to determine where execution time is being spent in your program and improve your code to reduce running time.
The main difference between sampler & Time profiler :
Sampler instrument operates upon a single process but Time Profiler operates upon a single/All processes.

Related

Time Profiler - Wait for app launch

When launching my app from a custom URL scheme, when app is not backgrounded, the launch sequence is taking longer then I would like. I want to use time profiler to see what methods are taking so long. I know on run there is an option for "Wait for App Launch" so I can launch it using the URL, but I don't see that under the profiling scheme. Does anyone know a way that I can launch the app fresh, using the URL, and have time profiler running on launch?
"see what methods are taking so long"
Do you suppose some method (or a few) are sopping up a lot of CPU time in themselves or by calling other methods that do?
If so, it will be easy to fix, but it's Not Likely.
More likely the time is spent in I/O of one sort or another, and you need to figure out why, not where.
If you're able to start it under a debugger (say by using #ChrisTruman's recommendation), then all you need to do is interrupt it with Ctrl-C, Ctrl-Break, Escape, or whatever key combination interrupts it.
Do this during the time when, subjectively, it is slow.
Let's suppose the startup is taking three times longer than you think it should.
If that's so, that means two thirds of the time is spent doing the unnecessary I/O or whatever it is.
That means each time you interrupt it, the probability is 2/3 that you will catch it in the act of doing whatever causes the slowness.
So interrupt it a few times, and each time just read the stack, look at variables, etc.
You will see why it's being slow.
Don't even look for where - that will appear by itself.
That's the basic idea behind this technique.

Does ProfileOptimization actually work?

One of the new performance enhanchements for .NET 4.5 is the introduction of the 'MultiCode JIT'.
See here for more details.
I have tried this, but it seems to have no effect on my application.
The reason why I am interested is that my app (IronScheme) takes a good long time to startup if not NGEN'd, which implies a fair amount of JIT'ng is involved at startup. (1.4 sec vs 0.1 sec when NGEN'd).
I have followed the instructions on how to enable this, and I can see a 'small' (4-12KB) is created. But on subsequent startup, it seems to have absolutely no effect on improving the startup time. It is still 1.4 sec.
Has anyone actually seen (or made) this work in practice?
Also, are there any limitations on which code will be 'tracked'? Eg: assembly loading contexts, transient assemblies, etc. I ask this as the created file never seems to grow, but I am in fact generating a fair amount of code (in a transient assembly).
One bug that I did encounter was that SetProfileRoot does not seem to understand a / as a path separator, make sure to use \ .
The rule of thumb we use at Microsoft is that Multicore JIT gets you about half way towards NGEN startup performance. Thus if your app starts in 0.1 seconds with NGEN and 1.4 seconds without NGEN, we would expect Multicore JIT startup to take about 0.75 seconds.
That being said, we had to put some limitations in place to guarantee that program execution order is the same with and without MCJ. MCJ will sometimes pause the background thread waiting for modules to be loaded by the foreground thread, and will abort background compilation if there is an assembly resolve or module resolve event.
If you want to find out what's happening in your case, we have ETW (Event Tracing For Windows) instrumentation of the MCJ feature and we will be releasing a version of PerfView soon which will be able to collect these events by if you take a trace of your app startup.
Update: PerfView has been updated to be able to show background JIT information. Here are the steps to diagnosing with the latest version (1.2.2.0):
Collect a trace using PerfView of your application startup, either using Collect->Run or Collect->Collect from the main PerfView menu.
Assuming you used Collect-> Run, put the name of your .exe in the Command text box, pick a filename (i.e. IronScheme.etl), select Background JIT from Advanced Options, and click Run Command.
Close your application and double click on the IronScheme.etl file that gets generated.
Double click on the JIT Stats view in the list underneath IronScheme.etl, you should see something like this in the view that pops up:
This process uses Background JIT compilation (System.Runtime.ProfileOptimize)
Methods Background JITTed : 2,951
Percent # Methods Background JITTed : 52.9%
MSec Background JITTing : 3,901
Percent Time JITTing is Background : 50.9%
Background JIT Thread : 11308
You can click on "View Raw Background Jit Diagnostics" to see all of the MCJ events in excel. One question I forgot to ask: are you running this on a multicore machine or multicore VM? It is a common mistake to test out MCJ in a VM that only has a single logical processor.
Calling Activator.CreateInstance during startup seems to kill MCJ?
Or rather that triggered an Assembly Resolve, which completely seems to stop MCJ. And never work after that. Maybe the MSDN docs should mention this.

Thread 1: Program received signal : "EXC_BAD_ACCESS"

I am currently programming a iPhone-app for my maturity research. But there is an behavior I don't understand: Sometimes when i compile my project there is:
Thread 1: Program received signal : "EXC_BAD_ACCESS".
But when I compile the same code a second, or a third time the code just runs fine and i can't get why. I use some MonteCarloSimulation but when it fails it fails executing one of the first 100 simulations. But when every thing runs fine it executes 1000000 simulations without an error.. Really strange isn't it?
Do you have any idea? Can this be an issue of Xcode or arc?
All other things just work perfect.
Do you have to get any further information? I can also send you my code as an email.
This usually means you're trying to access an object that has already been deallocated.
In order to debug these things, Objective C uses something called "NSZombie" that will keep those objects around so you can at least see what it is that's trying to be called. See this question for some details on how to use it.
This is typically caused by accessing some memory that's been corrupted, chances are you have a reference to an object which has been deleted. A lot of the time you may find that the memory where the object was located has not yet been overwritten, so when you attempt to access that memory your data is still intact and there is no problem, hence it working some of the time.
Another scenario would be that you've got some code writing into memory using a bad reference, so you're writing into an area you shouldn't be. Depending on the memory layout when the program starts, this could have no effect some of the time but cause something catastrophic at other times.

How does the debugger affect performance on iPhone?

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.

How to reduce the startup time for a typical iPhone 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.