1

Have profiled an app on an iPhone 4 using "Time Profiler" and "CPU Monitor" and trying to make sense of it.

Given that execution time is 8 minutes, CPU "Running Time" is around 2 minutes. About 67% of that is on the main thread, out of which 52% is coming from "own code".

Now, I can see the majority of time being spent in enumerating over arrays (and associated work), UIKit operations, etc.

The problem is, how do I draw any meaningful conclusions out of this data? i.e. there is something wrong going on here that needs fixing.

I can see a lot of CPU load over that running time (median at 70%) that isn't "justifiable" given the nature of the app.

Having said that, there are some things that do stand out. Parsing HTTP responses on the main thread, creating objects eagerly (backed up by memory profiling as well).

However, what I am looking for here is offending code along with useful conclusions solely based on CPU running time. i.e. spending "too much" time here.

enter image description here

Update

Let me try and elaborate in order to give a better picture.

Based on the functional requirements of this app, I can't see why it shouldn't be able to run on an iPhone 3G. A median CPU usage of around 70%, with a peak of 97% only looks like a red flag on an iPhone 4.

The most obvious response to this is to investigate the code and draw conclusions from that.

What I am hoping for is a categorical answer of the following form

  1. if you spend anywhere between 25% - 50% of your time on CA, there is something wrong with your animations
  2. if you spend 1000ms on anything related to UIKit, better check your processing

Then again, maybe there aren't any answers only indications of things being off when it comes to running time and CPU usage.

qnoid
  • 2,346
  • 2
  • 26
  • 45

3 Answers3

0

Answer for question "is there something wrong going on here that needs fixing" is simple: do you see the problem while using application? If yes (you see glitches in animation, or app hang for a while), you probably want to fix it. If not, you may be looking for premature optimization.
Nonetheless, parsing http responses in main thread, may be a bad idea.

Maciej Kozieł
  • 959
  • 11
  • 24
  • Does this mean "there aren't any meaningful conclusions" from running time/CPU usage alone? The app does "feel" sluggish when it comes to animations, scrolling a view, moving around a map. Question is, how do you tie the two? – qnoid Nov 12 '13 at 18:13
  • You can say, that application is quite intensive in cpu consumption, but you know nothing about distribution of that process. What you are looking for, are high percentages down the tree. And as I said, if you parse responses in main thread (let's say, while scrolling table view) your application may become 'sluggish'. – Maciej Kozieł Nov 12 '13 at 18:18
  • I find it surprising that anyone would say that a performance issue that cannot be noticed by the user is not a problem. It might not be the highest priority but your users will notice the reduction in battery power and possibly slowing of other background tasks. If the OS maintainers spend so much time optimising their systems don't you think app developers should follow suit? – andy.xyz Nov 12 '13 at 20:30
  • Generally, you are right, but I think this discussion is not on that topic. If your app have to do something, it will consume that cpu power anyway. Making things working in background thread won't make it use less power, it will just improve overall experience. You are making this question too general. If you want to optimise battery usage, you probably want to use "Energy Diagnostics" tool in instruments. Edit: Beside that, I've written in my first comment, what that running time means, and where you should look for more details. – Maciej Kozieł Nov 12 '13 at 20:53
  • "If your app have to do something, it will consume that cpu power anyway.", can't say I agree on principle. There are algorithms of different complexity, batched operations, data transformation that can happen per request rather all up front. There is a difference between having peaks of CPU usage as opposed to a normalised one over time. – qnoid Nov 12 '13 at 23:46
0

In dev presentations Apple have pointed out that whilst CPU usage is not an accurate indicator in the simulator it is something to hold stock of when profiling on device. Personally I would consider any thread that takes significant CPU time without good reason a problem that needs to be resolved. Find the time sinks, prioritise by percentage, and start working through them. These may not be visible problems now but they will begin to, if they have not already, degrade the user's experience of the app and potentially the device too.

Check out their documentation on how to effectively use CPU profiling for some handy hints.

If enumeration of arrays is taking a lot of time then I would suggest that dictionaries or other more effective caches could be appropriate, assuming you can spare some memory to ease CPU.

An effective approach may be to remove all business logic from the main thread (a given) and make a good boundary layer between the app and the parsing / business logic. From here you can better hook in some test suites that could better tell you if the code is at fault or if it's simply the significant requirements of the app UI itself...

andy.xyz
  • 2,567
  • 1
  • 13
  • 18
  • I cannot agree with part of your answer. If problems are not visible now (I assume that you are testing your app on least powerful device you want support), it's very unlikely, that anything will go worse on newer devices. If problems occurred during development; it's great time to fix them. If something goes wrong, you can always fix it in update. Don't understand me wrong; I love to fix even smallest imperfections, but this is great time killer, which you generally should't try at work unless completely necessary. – Maciej Kozieł Nov 12 '13 at 21:08
  • You have a fair point by I still stand by my comment. One mistake that can be made during testing is to use new devices with no background services in a strong signal area. If any of these things is no longer true the experience gets worse. We need to know the system is capable of handling some other tasks at the same time. If your app is managing to stay afloat but only just then what happens when a more important task needs to run i.e. incoming phone call? – andy.xyz Nov 12 '13 at 21:23
  • Yes, and that will be a wrong way of making tests. You example is pretty extreme (cpu intensive app, while being in background), which off course needs special considerations. I think we both have a right; it depends on what you are asking for. And I think, both of us are quite far from original question now. My point is to not focus on small things, unless necessary (you can see the problem, or suspects that something big is going on). I agree with answer in: http://programmers.stackexchange.com/questions/80084/is-premature-optimization-really-the-root-of-all-evil – Maciej Kozieł Nov 12 '13 at 21:39
  • The post you link to is a good one. I suppose I was less implying that as new devices come along it gets worse rather than as new features are added it gets worse. Clearly at that point you could see the problem and address it but it sounds like the OP is taking on an app and trying to understand it's issues before piling on new feature rather than looking at an app ready for submission to determine if it's OK. Pretty much just 2 pence worth though. – andy.xyz Nov 12 '13 at 21:45
  • Sure. In case described in question, it's best to check deeper in cpu usage tree, and find hight percentages. Information about running time vs execution time tells only, that application was quite cpu intensive during recording period. And as you noticed, OP is trying to fix issues with app, because it became 'sluggish', which is quite a good time for using instruments. It wasn't clear at the beginning, so that's why I've written about possible premature optimization. – Maciej Kozieł Nov 12 '13 at 22:14
0

Eight minutes?

Without beating around the bush, you want to make your application faster, right?

Forget looking at CPU load and wondering if it's the right amount. Forget guessing if it's HTTP parsing. Maybe it is, but guessing won't tell you. Forget rummaging around in the code timing things in hopes that you will find the problem(s).

You can find out directly why it is spending so much time. Here's the method I use, and here's an (amateurish) video of it.

Here's what will happen if you do that. First you will find something you would never have guessed, and when you fix it you will lop a big chunk off that 8 minutes, like maybe down to 6 minutes. Then you do it again, and lop off another big chunk. You repeat until you can't find anything to fix, and then it will be much faster than your 8 minutes.

OK, now the ball is in your court.

Community
  • 1
  • 1
Mike Dunlavey
  • 40,059
  • 14
  • 91
  • 135
  • Not sure I follow tbh. By 8 minutes of execution time I mean how long the app has been running, not the CPU doing work. I am not looking for the "go faster" button. What I am looking though is what's keeping that CPU busy and whether or not it's legitimate. However loosely you want to put it. – qnoid Nov 13 '13 at 00:19
  • @qnoid: It doesn't matter. It's elapsed time. It could be CPU, it could be I/O. Whatever it is, it's much more than it needs to be. – Mike Dunlavey Nov 13 '13 at 00:22
  • Or "it could" simply be idle (i.e. waiting on user input) :) – qnoid Nov 13 '13 at 00:28
  • @qnoid: If it's waiting for user input its CPU usage would be zero. Your time is better spent learning the technique in that video than debating. – Mike Dunlavey Nov 13 '13 at 00:29
  • Will do first thing tomorrow as it's after midnight here. :) by the way, mean no disrespect nor debating; simply stating the facts. – qnoid Nov 13 '13 at 00:33
  • An informative video Mike. Thanks for sharing. Not sure how one can incorporate this methodology on an app. UI will need to be scripted for once. – qnoid Nov 13 '13 at 08:05